zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    个人常用Git操作记录
    JavaScript引擎基本原理:Shapes和Inline Caches
    Promise.then(a, b)与Promise.then(a).catch(b)问题详解
    p标签中的文本换行
    Vue初始化
    关于vue的源码调试
    关于extjs表单布局的几种方式
    sublime text3安装、注册及常用插件
    chrome扩展程序开发
    关于Git的简单使用
  • 原文地址:https://www.cnblogs.com/Opaser/p/4857834.html
Copyright © 2011-2022 走看看