• HDU 4512 HDOJ 吉哥系列故事——完美队形I 腾讯2013初赛第三场


    http://acm.hdu.edu.cn/showproblem.php?pid=4512

    题目意思:给定一个序列,求最长回文子序列,满足从中点到两端依次递减。

    先看LCIS最长公共上升子序列。

      dp[i]表示当前以下标i结束的最长公共上升子序列。

    我们让第一个序列为原序列,第二个序列为原系列的反向。

    则,也就是说,第二个序列的顺序为原序列的下标[n-1,0],设为j

    当j枚举到k时,对于dp[0] ~ dp[k-1],都可以得到原序列的一个长度为2*dp[i]的题目要求的子序列。

    可是对于,dp[k],我们怎么判断此时,两个序列是否存在交集呢?假如存在交集,此时题目要求的子序列长度为2*dp[k] - 1

    这样考虑,假如此时的序列没有交集,则此时两个序列的最长公共上升子序列,在序列二中的起始坐标必然不是k

      那么它必然在j=[k+1,n-1]的时候已经出现过,并以dp[k]*2更新过ans

    也就是说根本不用考虑嘛。。。直接将用dp[k]*2-1更新ans,答案并不会有错。

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 int n,ans,a[201],dp[201];
     5 inline void Max(int &a,const int b){if(b>a) a=b;}
     6 int main()
     7 {
     8     int T;
     9     scanf("%d",&T);
    10     while(T--){
    11         scanf("%d",&n);
    12         memset(dp,0,sizeof dp);
    13         for(int i=0;i<n;i++) scanf("%d",a+i);
    14         ans=1;
    15         for(int k=n-1;k>=0;k--){
    16             int x=a[k],mx=0;
    17             for(int i=0;i<=k;i++){
    18                 if(a[i]<x) Max(mx,dp[i]);
    19                 else if(a[i]==x) dp[i]=mx+1;
    20                 if(i<k) Max(ans,dp[i]*2);
    21                 else Max(ans,dp[i]*2-1);
    22             }
    23         }
    24         printf("%d\n",ans);
    25     }
    26     return 0;
    27 }
  • 相关阅读:
    CentOS7 安装MongoDB 3.0服务
    PXE批量部署linux操作系统
    centos的软件安装方法rpm和yum
    第二章:Posix IPC
    第一章:简介
    Unix网络编程--卷二:进程间通信
    Unix网络编程--卷二:FAQ
    linux下samba环境搭建
    Linux下缓冲区溢出攻击的原理及对策(转载)
    lsof
  • 原文地址:https://www.cnblogs.com/hundundm/p/2976503.html
Copyright © 2020-2023  润新知