HDU4745 Two Rabbits【区间DP】

题目链接:HDU4745 Two Rabbits

题意:有一段环形字符串,两个人相对而行,要使得他们走过的字母序列相同的最长长度是多少;实际上就是求字符串中最长的回文子序列的长度,最终答案是取长度为n的区间里最长的长度 和 长度为n-1的区间里最长的长度+1 的最大值;+1是因为n-1的区间剩下的那个可以被同时当作起点,注意是环形字符串;

分析:根据差分,dp[l][r]=max(dp[l][r-1],dp[l+1][r]);当a[l]=a[r]时,dp[l][r]=max(dp[l][r],dp[l+1][r-1]+2),最长的再加上两端;

#include<bits/stdc++.h>
using namespace std;
const int maxn=2007;
int dp[maxn][maxn];
int a[maxn];
int n;
void rua()
{
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i+n]=a[i];
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n+n;i++) dp[i][i]=1;
    for(int i=1;i<n+n;i++)
        if(a[i]==a[i+1]) dp[i][i+1]=2;
        else dp[i][i+1]=1;
    for(int i=3;i<=n;i++)
        for(int l=1;l+i-1<=n+n;l++)
        {
            int r=l+i-1;
            dp[l][r]=max(dp[l][r-1],dp[l+1][r]);
            if(a[l]==a[r]) dp[l][r]=max(dp[l][r],dp[l+1][r-1]+2);
        }
    int ans=0;
    for(int i=1;i<=n+1;i++) ans=max({ans,dp[i][i+n-1],dp[i][i+n-2]+1});
    printf("%d\n",ans);
}
int main()
{
    while(~scanf("%d",&n) && n) rua();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43813163/article/details/102554995