「SCOI2014」方伯伯的玉米田

Posted ympc2005

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「SCOI2014」方伯伯的玉米田相关的知识,希望对你有一定的参考价值。

动态规划+数据结构优化

每次操作区间的右端点一定为n,因为要尽量的让后面的数更大

记 f[i][k] 为以第i个玉米为结尾一共操作了k次的最长不下降序列的长度

因为每次操作右端点为n,左端点小于等于i

所以此时i的高度为 h[i] + k

则 f[i][k] = max(f[j][l]) + 1 // h[j] + l <= h[i] + k, j < i, l <= k

将每个状态 f[i][k] 可以表示为 (k, h[i] + k) // 操作次数,结尾高度

每次转移相当于取 (K, H) K <= k, H <= h[i] + k的最大值

可以用二维树状数组来维护

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e4 + 5, K = 505, H = 6005;
 5 
 6 int n, k, h[N], Max, f[N][K], tr[K][H], ans;
 7 
 8 int query(int x, int y) {
 9     int i = x, res = 0;
10     while (i) {
11         int j = y;
12         while (j) {
13             res = max(res, tr[i][j]);
14             j -= (j & (-j));
15         }
16         i -= (i & (-i));
17     }
18     return res;
19 }
20 
21 void update(int x, int y, int val) {
22     int i = x;
23     while (i <= k + 1) {
24         int j = y;
25         while (j <= Max) {
26             tr[i][j] = max(tr[i][j], val);
27             j += (j & (-j));
28         }
29         i += (i & (-i));
30     }
31     return;
32 }
33 
34 int main() {
35     cin >> n >> k;
36     for (int i = 1; i <= n; i++) {
37         scanf("%d", &h[i]);
38         Max = max(Max, h[i] + k);
39     }
40     for (int i = 1; i <= n; i++)
41         for (int j = k; j >= 0; j--) {
42             f[i][j] = query(j + 1, h[i] + j) + 1;
43             ans = max(ans, f[i][j]);
44             update(j + 1, h[i] + j, f[i][j]);
45         }
46     cout << ans << endl;
47 }

 

以上是关于「SCOI2014」方伯伯的玉米田的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3594 [Scoi2014]方伯伯的玉米田

[SCOI2014]方伯伯的玉米田

[SCOI2014]方伯伯的玉米田

[BZOJ3594][Scoi2014]方伯伯的玉米田

BZOJ 3594[Scoi2014]方伯伯的玉米田

bzoj3594[Scoi2014]方伯伯的玉米田