zoukankan      html  css  js  c++  java
  • hdu6357 Hills And Valleys

    传送门

    题目大意

    给定一个序列A,求翻转A中一个区间之后的最长不降子序列的长度即翻转的区间

    分析

    发现直接枚举翻转的区间的话是无论如何都不行的,于是有一个非常神奇的做法。我们再设一个序列B = {0,1,2,3,4,5,6,7,8,9},然后我们枚举翻转B中的哪一段,假设我们翻转[5,8]z这一段,则得到B' = {0,1,2,3,4,5,8,7,6,5,8,9},然后设dp[i][j]表示A考虑到第i个,B'考虑到第j个,直接dp转移即可。最终输出的翻转区间单独设数组然后一起转移就行了。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    #include<queue>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    int dp[100100][30],a[100100],b[1100],n,t,le,ri,ansl,ansr,Ans,cnt;
    int L[100100][30],R[100100][30];
    char s[100100];
    inline void solve(){
        int i,j,k;
        for(i=1;i<=n;i++)
          for(j=1;j<=cnt;j++){
              dp[i][j]=dp[i-1][j];
              L[i][j]=L[i-1][j];
              R[i][j]=R[i-1][j];
              if(a[i]==b[j]){
                dp[i][j]=dp[i-1][j]+1;
                if(j==le&&!L[i][j])L[i][j]=i;
                if(j==ri)R[i][j]=i; 
            }
            if(dp[i][j-1]>dp[i][j]){
              dp[i][j]=dp[i][j-1];
              L[i][j]=L[i][j-1];
              R[i][j]=R[i][j-1];
            }
          }
        return;
    }
    int main(){
        int i,j,k;
        scanf("%d",&t);
        while(t--){
          cnt=0;
          for(i=0;i<=9;i++)b[++cnt]=i;
          scanf("%d",&n);
          scanf("%s",s);
          for(i=0;i<n;i++)a[i+1]=s[i]-'0';
          le=ri=ansl=ansr=1;
          solve();
          Ans=dp[n][cnt];
          for(i=0;i<9;i++)
            for(j=i+1;j<=9;j++){
              cnt=0;
              for(k=0;k<=i;k++)b[++cnt]=k;
              le=cnt+1;
              for(k=j;k>=i;k--)b[++cnt]=k;
              ri=cnt;
              for(k=j;k<=9;k++)b[++cnt]=k;
              solve();
              if(Ans<dp[n][cnt]&&L[n][cnt]&&R[n][cnt]){
                  Ans=dp[n][cnt];
                  ansl=L[n][cnt];
                  ansr=R[n][cnt];
              }
            }
          printf("%d %d %d
    ",Ans,ansl,ansr);
        }
        return 0;
    }
  • 相关阅读:
    关于python列表中的赋值问题
    $' ': command not found报错问题
    0day安全-软件漏洞分析技术(第二版)——Crack实验一
    PNI12927 学习笔记
    Mini2440串口通信之DMA
    Mini2440串口通信
    Mini2440的外部中断编写
    VM中设置redhat为静态IP
    ldr指令小记
    Makefile文件编写小记
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9791636.html
Copyright © 2011-2022 走看看