hdu4521小明系列问题——小明序列

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4521

题意:中文题。

分析:最长上升子序列,距离大于d。一点点变动而已,用线段树或树状数组维护一下小当前值a[i]且在i-d-1之前的所有的dp[j]就行了。

代码:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=100010;
const int MAX=1000000100;
const int mod=100000000;
const int MOD1=1000000007;
const int MOD2=1000000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=1000000007;
const int INF=1000000010;
typedef double db;
typedef unsigned long long ull;
int a[N],f[N],dp[N];
void add(int x,int y) {
    for (;x<=100001;x+=x&(-x)) f[x]=max(f[x],y);
}
int get(int x,int ret=0) {
    if (x<=0) return 0;
    for (;x;x-=x&(-x)) ret=max(ret,f[x]);
    return ret;
}
int main()
{
    int i,n,d,ans;
    while (scanf("%d%d", &n, &d)!=EOF) {
        memset(f,0,sizeof(f));
        memset(dp,0,sizeof(dp));
        ans=1;
        for (i=1;i<=d+1;i++) dp[i]=1;
        for (i=1;i<=n;i++) scanf("%d", &a[i]),a[i]++;
        for (i=d+2;i<=n;i++) {
            add(a[i-d-1],dp[i-d-1]);
            dp[i]=get(a[i]-1)+1;ans=max(ans,dp[i]);
        }
        printf("%d\n", ans);
    }
    return 0;
}


你可能感兴趣的:(hdu4521小明系列问题——小明序列)