hdu 4745 Two Rabbits

杭州网络赛真题

比赛的时候觉得这题出的真好。。把知识结合的如此巧妙。。。就是做不出来。。。

其实好像也不难啊,还是dp,要想清楚过程,有哪些种情况


求环上的最大回文子环,

递推方程:dp[i][j] = max(max(dp[i][j], dp[i+1][j-1] +2), max(dp[i+1][j], dp[i][j-1])); 

求出每两点间的最长子序列

确实,如果是最长子串,那么一定是对称的,那么两头顺着都是一样的,就2个2个加啊,然后跟相邻的比


 

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
using namespace std;

int s[2005],dp[2005][2005];

int main()
{
    int i,j,l,ans,n;
    while(scanf("%d",&n)&&n)
    {
        for(i=0;i<n;i++)
        {
            scanf("%d",&s[i]);
            s[i+n]=s[i];
        }
        if(n==1){
            printf("1\n");
            continue;
        }
        memset(dp,0,sizeof dp);
        for(i=0;i<n+n;i++)
            dp[i][i]=1;
        for(l=2;l<=n;l++)//
        {
            for(i=0;i+l-1<n+n;i++)
            {
                j=i+l-1;
                if(s[i]==s[j])
                    dp[i][j]=max(dp[i][j], dp[i+1][j-1]+2);
                else dp[i][j]=max(dp[i][j], dp[i+1][j-1]);
                dp[i][j]=max(dp[i][j],max(dp[i+1][j],dp[i][j-1]));
            }
        }
        ans=0;
        for(i=0;i<n;i++)
            ans=max(dp[i][i+n-1],ans);
        for(i=0;i<n;i++)
            ans=max(dp[i][i+n-2]+1,ans);
        printf("%d\n",ans);
    }
    return 0;
}


 


 

posted on 2013-10-11 16:32  云编程的梦  阅读(194)  评论(0编辑  收藏  举报

导航