杭州网络赛真题
比赛的时候觉得这题出的真好。。把知识结合的如此巧妙。。。就是做不出来。。。
其实好像也不难啊,还是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 "); 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 ",ans); } return 0; }