Dynamic Planning is the first thing we can see.
Then write the equation: F [I] indicates the maximum number of I blocks that meet the requirements.
Then f [I] = max (F [J] + 1)
J meets the following three conditions:
(1) j <I
(2) A [J] <A [I]
(3) A [I]-A [J] <= I-j
Deformation (3): A [I]-I <= A [J]-J... (4)
At this time, the zyh God told me that (2) + (3) can launch (1), that is, only two conditions (2) and (4) can be met.
The obtained method is as follows: first sort (first keyword A [I]-I in ascending order, second keyword A [I] in descending order), and then directly obtain the lis of the new series.
In fact, when lis is obtained here, the maximum value of [1, I] is required each time. Line tree maintenance is not required, as long as the tree array is enough.
1 /************************************************************** 2 Problem: 1109 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:332 ms 7 Memory:3148 kb 8 ****************************************************************/ 9 10 #include <cstdio>11 #include <cmath>12 #include <algorithm>13 14 using namespace std;15 16 struct Rec{17 int num, x;18 } a[150000];19 int ans, n, f[150000], Bit[150000];20 21 bool cmp(Rec a, Rec b){22 return a.x == b.x ? a.num < b.num : a.x > b.x;23 } 24 25 inline int lowbit(int x){26 return x & (-x);27 }28 29 int query(int x){30 if (!x) return 0;31 int res = 0;32 while (x){33 res = max(res, Bit[x]);34 x -= lowbit(x);35 }36 return res;37 }38 39 void add(int x, int y){40 while (x <= n){41 Bit[x] = max(Bit[x], y);42 x += lowbit(x);43 }44 }45 46 int main(){47 scanf("%d", &n);48 for (int i = 1; i <= n; ++i){49 scanf("%d", &a[i].num);50 a[i].x = a[i].num - i;51 }52 sort(a + 1, a + n + 1, cmp);53 54 for (int i = 1; i <= n; ++i){55 if (a[i].x > 0) continue;56 int X = query(a[i].num - 1);57 f[i] = X + 1;58 ans = max(ans, f[i]);59 add(a[i].num, f[i]);60 } 61 printf("%d\n", ans);62 return 0;63 }View code
Bzoj1109 [poi2007] stacked wood klo