Two Rabbits HDU - 4745
考察:区间DP
思路:
观察样例可以发现,当两只兔子在同一块石头时,ans+1,在不同但质量相同的石头时,ans+=2.这里就有点像密码脱落那道题求回文序列的长度(不是子串).但是根据样例2,我们求出来的最大回文序列长度只有3,原因是在回文序列外的单个字符没有计入.由此可以发现ans有两部分组成,假设分段点为k,ans = f[l][k]+f[k+1][r].因为[l,r]区间可能存在>1个回文子串.但是计入的回文子串一定<=2.因为跳的方向有限制,所以只需要在计算f[1][n]时枚举一个中断点.
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int N = 1010; 6 int n,s[N],f[N][N]; 7 int main() 8 { 9 while(scanf("%d",&n)!=EOF&&n) 10 { 11 memset(f,0,sizeof f); 12 for(int i=1;i<=n;i++) scanf("%d",&s[i]); 13 for(int i=1;i<=n;i++) f[i][i] = 1; 14 for(int len=2;len<=n;len++) 15 for(int i=1;i+len-1<=n;i++) 16 { 17 int j = i+len-1; 18 if(s[i]==s[j]) f[i][j] = f[i+1][j-1]+2; 19 else f[i][j] = max(f[i+1][j],f[i][j-1]); 20 } 21 int ans = 0; 22 for(int i=1;i<=n;i++) ans = max(f[1][i]+f[i+1][n],ans); 23 printf("%d\n",ans); 24 } 25 return 0; 26 }