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;
}
/*
*/

 

posted @ 2018-06-17 15:13  NotNight  阅读(127)  评论(0编辑  收藏  举报