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;
}
浙公网安备 33010602011771号