【HNOI2004]アルカノイド

luoguP2291 [HNOI2004]ブレイクアウト

セット([I]、[J F \ ] [k]は、\) を表し\を(私は\)の列は、ノック前\(J \)レンガ、総ノック\(Kを\)得られた最大レンガ番目利点。
およびセクション\(Iは\)状態のみ列\(I + \ 1)の関連する列の状態。
ので後方\(DP \)
\(F [I] [J] [K] = \最大{(F [I]
[J] [K]、\ fは[iが\ + \ 1] [T] [K \ - \ J])} \) と状態遷移に関係なく回避は、我々は\(F \ )に割り当てられた配列の初期値\( - INF \)

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define il inline
#define rg register
#define gi read<int>
using namespace std;
const int O = 55;
template<class TT>
il TT read() {
  TT o = 0, fl = 1; char ch = getchar();
  while (!isdigit(ch)) fl ^= ch == '-', ch = getchar();
  while (isdigit(ch)) o = o * 10 + ch - '0', ch = getchar();
  return fl ? o : -o;
}
int n, m, ans, a[O][O], s[O][O], f[O][O][O*O];
int main() {
  memset (f, -1, sizeof f);
  n = gi(), m = gi();
  for (int i = 1; i <= n; ++i)
      for(int j = 1; j <= n - i + 1; ++j)
          a[i][j] = gi();
  for (int i = 1; i <= n; ++i)
      for (int j = 1; j <= n - i + 1; ++j)
          s[i][j] = s[i][j - 1] + a[j][i];
  f[n + 1][0][0] = 0;
  for (int i = n; i; --i) {
      for (int j = 0; j <= n - i + 1; ++j)
          for (int k = j; k <= min(m, (n - i + 1) * (n - i + 2) >> 1); ++k)
              for (int t = j ? j - 1 : 0; t <= n - i; ++t)
                  if (f[i + 1][t][k - j] >= 0){
                      f[i][j][k] = max(f[i][j][k], s[i][j] + f[i + 1][t][k - j]);
                      ans = max(ans, f[i][j][k]);
                  }
  }
  printf("%d\n", ans);
  return 0;
}

おすすめ

転載: www.cnblogs.com/lylyl/p/11668154.html