[SCOI2014]方伯伯的玉米田

一开始看错题目惹,导致错过了这题的关键\(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;
}
posted @ 2021-05-26 20:48  fhq_treap  阅读(46)  评论(0编辑  收藏  举报