bzoj 1109
思路:我们考虑dp[ i ] 表示的是 i 在指定位置上 的最大个数,
dp[ i ] = max(dp[ j ] + 1)
j需要满足3个条件
1. j < i
2. a[ j ] < a[ i ]
3. a[ i ] - a[ j ] <= i - j
通过 2,3 我们能推出1
所以其实是个二维偏序问题
将序列按 a[ i ]排序后可以用树状数组解决或者转化为LIS问题。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 +7; int a[N], n; pii p[N]; void modify(int x, int v) { for(int i = x; i < N; i += i & -i) { a[i] = max(a[i], v); } } int getMx(int x) { int ans = 0; for(int i = x; i; i -= i & -i) { ans = max(ans, a[i]); } return ans; } bool cmp(pii a, pii b) { if(a.fi == b.fi) return a.se - a.fi > b.se - b.fi; return a.fi < b.fi; } int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &p[i].fi); p[i].se = i; } sort(p + 1, p + 1 + n, cmp); int ans = 0; for(int i = 1; i <= n; i++) { if(p[i].se - p[i].fi < 0) continue; int mx = getMx(p[i].se - p[i].fi + 1); modify(p[i].se - p[i].fi + 1, mx + 1); ans = max(ans, mx + 1); } printf("%d\n", ans); return 0; } /* */