Dynamic programming + data structure optimization
Every time the right point greater operating range bound for n, because to try to get behind the numbers
Note F [i] [k] for the i-th to corn ending the total length of the longest operation sequence does not fall times k
Since each operation is a right end point n, the left point is less than equal to i
So in this case i is a height h [i] + k
则 f[i][k] = max(f[j][l]) + 1 // h[j] + l <= h[i] + k, j < i, l <= k
Each state f [i] [k] can be expressed as (k, h [i] + k) // number of operations, the end of the height
Taking each transition corresponds to (K, H) K <= k, H [i] + maximum value <= h k of
You can use a two-dimensional array to maintain the tree
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 }