2015-10-06 21:49:54
这题说的是个给了一个数组,然后删除任意起点的一个连续的L个数,然后求最长递增子序列《是递增,不是非递减》,用一个树状数组维护一下就ok了
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio> #include <cmath> using namespace std; const int maxn=100005; int A[maxn],B[maxn]; int dp[maxn][2]; int NUM[maxn][3],N; int lowbit(int x) { return x&(-x); } void add(int loc, int v,int op) { while(loc<=N) { NUM[loc][op]=max(v,NUM[loc][op]); loc+=lowbit(loc); } } int sum(int loc, int op) { int ans=0; while(loc>0) { ans=max(ans,NUM[loc][op]); loc-=lowbit(loc); } return ans; } int main() { int cas; scanf("%d",&cas); for(int cc=1; cc<=cas; cc++) { int n,L; scanf("%d%d",&n,&L); int id=0; for(int i=0; i<n; i++) { scanf("%d",&A[i]); B[i]=A[i]; if(A[i]<A[id])id=i; } if(L==n){ printf("Case #%d: %d\n",cc,0);continue; } B[n]=A[id]-1; sort(B,B+(n+1)); N=unique(B,B+(n+1))-B; memset(NUM,0,sizeof(NUM)); for(int i=0; i<n; i++){ A[i]=lower_bound(B,B+N,A[i])-B+1; } int ans=0; for(int i=0; i<n; i++) { dp[i][0]=dp[i][1]=0; int Loc=A[i]; int AA=sum(Loc-1,0); dp[i][0]=AA+1; AA=sum(Loc-1,1); dp[i][0]=max(dp[i][0],AA+1); if(n-L>i){ dp[i][1]=sum(Loc-1,2)+1; } if(i-L>=0){ add(A[i-L],dp[i-L][1],1); } if(i>=L){ add(A[i],dp[i][0],0); } if(n-L>i){ add(A[i],dp[i][1],2); } ans=max(max(dp[i][0],dp[i][1]),ans); } printf("Case #%d: %d\n",cc,ans); } return 0; }
原文:http://www.cnblogs.com/Opaser/p/4857834.html