hdu5489 树状数组+dp


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
",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
",cc,ans);
        }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Opaser/p/4857834.html