hdu 4632 Palindrome subsequence
题意:给出一段序列,让我们找出最多的是回文串的子序列;
思路:区间DP;
我们先初始化长度为1时的答案 ,然后再从长度为2开始逐一枚举;
当我们求dp【i】【j】区间的答案时,
1.我们可以dp【i+1】【j】+dp【i】【j-1】-dp【i+1】【j-1】,这样就能处理出原本已经得到的答案;
2.然后我们需要看看两端位置是否相同,如果相同的话,则可以有这两个端点与区间(i+1,j-1)进行匹配,有dp【i+1】【j-1】
其次,可以单独由这两个点匹配,再+1;
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e3+10; 4 const int mod=1e4+7; 5 char a[maxn]; 6 int dp[maxn][maxn]; 7 int main() 8 { 9 int T; 10 scanf("%d",&T); 11 int Case=0; 12 while(T--){ 13 scanf("%s",a+1); 14 int n=strlen(a+1); 15 memset(dp,0,sizeof(dp)); 16 for(int i=1;i<=n;i++) dp[i][i]=1; 17 for(int len=1;len<=n;len++){ 18 for(int i=1;i+len<=n;i++){ 19 int j=i+len; 20 if(a[i]==a[j]) dp[i][j]=(dp[i+1][j-1]+mod+1)%mod; 21 dp[i][j]=(dp[i][j]+dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+mod)%mod; 22 } 23 } 24 printf("Case %d: %d\n",++Case,dp[1][n]); 25 } 26 return 0; 27 }