一开始看错题目惹,导致错过了这题的关键\(trick\)
考虑每次操作肯定都是一个\([k,n]\)的,证明贪心一下就好了。
那么考虑记\(f[i][k]\)为前\(i\)个数用了\(k\)次。
那么只要满足\(j < i \ and\ a_j + k_j <= a_i + k_i \ and\ k_j < k_i\)就能转移了。
由于前一个偏序关系是自然的。
我们只要找一个东西来维护后面那个就好了。
[SCOI2014]方伯伯的玉米田
#include <cstdio>
inline int max(const int x, const int y) {return x > y ? x : y;}
int a[10005], dp[10005][505], c[505][5505], n, m;
void update(const int x, const int y, const int d) {
for (int i(x); i <= m + 1; i += (i & ~i + 1))
for (int j(y); j <= 5500; j += (j & ~j + 1)) c[i][j] = max(c[i][j], d);
}
int query(const int x, const int y) {
int ans(0);
for (int i(x); i; i -= (i & ~i + 1))
for (int j(y); j; j -= (j & ~j + 1)) ans = max(ans, c[i][j]);
return ans;
}
int main() {
scanf("%d%d", &n, &m);
for (int i(1); i <= n; ++ i) scanf("%d", a + i);
for (int i(1); i <= n; ++ i)
for (int j(m); j >= 0; -- j)
update(j + 1, a[i] + j, dp[i][j] = query(j + 1, a[i] + j) + 1);
printf("%d", query(m + 1, 5500));
return 0;
}