BOJ 20367 - 3 Slot Matching

image.png

2개는 계속 들고다닐 수 없다.

그 다음턴에 무조건 두 개중 하나와 결합해야 한다.

$dp[i][j] = i$ 번째 막대를 볼 때 저장된 막대가 $j$ 일 때 최댓값

라고 정의하고 간단히 DP를 정의할 수 있다.

void solve() {
   int n;
   cin >> n;
   vi a(n + 1);
   fv1(a);
   vvi dp(n + 5, vi(n + 5, -1));
   function<int(int, int)> fn = [&](int i, int j) -> int {
      if (i > n) return 0;
      int &ret = dp[i][j];
      if (~ret) return ret;
      ret = 0;

      if (j == 0) {
         ret = fn(i + 1, i);
      } else {
         // 이전것과 이것을 결합할 때
         maxa(ret, fn(i + 1, 0) + a[j] * a[i]);
         if (i != n) {
            maxa(ret, fn(i + 2, j) + a[i] * a[i + 1]);
            maxa(ret, fn(i + 2, i) + a[j] * a[i + 1]);
         }
      }

      return ret;
   };
   cout << fn(1, 0);
}

Tags:

Categories:

Updated:

Comments