zoukankan      html  css  js  c++  java
  • hdu 4745 Two Rabbits 环形最长回文子序列

    Two Rabbits

    ---------------------------------------------------------------------

    模型可以转化为求长度为n的序列的最长回文子序列

    方法为枚举起点+记忆化+环形dp

    用next(i)代替i++,prev(i)代替i--

    f[i][j]表示环(i,j)的最长回文子序列。

    若i=j则环区间为空,

    若i>j则区间为 i i+1 i+2 ... n-1 ... j-2 j-1 j

    若i<j则区间为 i i+1 ... j-1 j

    枚举起点i, 分为以i为起点向两端寻找与不以i为起点但是环区间在 (i+1,i) 两端两种情况。

    ---------------------------------------------------------------------

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    
    using namespace std;
    
    const int maxn=1111;
    int a[maxn];
    int f[maxn][maxn];
    int n;
    int prev(int x){
        return (x-1+n)%n;
    }
    int next(int x){
        return (x+1)%n;
    }
    int dp(int l,int r){
        if (l==r) return 1;
        if (next(l)==r) return 1+(a[l]==a[r]);
        if (f[l][r]!=-1) return f[l][r];
        if (a[l]==a[r]) return f[l][r]=dp(next(l),prev(r))+2;
        return f[l][r]=max(dp(next(l),r),dp(l,prev(r)));
    }
    int main()
    {
        int ans;
        while (~scanf("%d",&n)){
            if (n==0) break;
            ans=0;
            memset(f,-1,sizeof(f));
            for (int i=0;i<n;i++){
                scanf("%d",&a[i]);
            }
            if (n==1) ans=1;
            else if (n==2) ans=2;
            else{
                for (int i=0;i<n;i++){
                    ans=max(ans,dp(next(i),prev(i))+1);
                    //ans=max(ans,dp(i,prev(i)));
                    ans=max(ans,dp(next(i),i));
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    前端
    wampserver无法进入到phpmyadmin
    wordpress搭载wampserver上的问题
    电脑不显示网络信号,却能连上网
    读书TODO
    秒杀活动,怎么设计全套技术方案
    淘宝返利知识普及
    如何给变量命名
    一段SQL代码的压缩:从974行到96行,十倍压缩
    nginx一致性hash及应用场景。
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681578.html
Copyright © 2011-2022 走看看