hdu 4632

题意:给你一个长度为n的字符串,求包含几个回文序列?

分析:dp[i][j]表示区间[l,r]内包含的回文序列的个数,

dp[i][j] = dp[i+1][j] + dp[i][j-1] - dp[i+1][j-1];  if (s[i] == s[j] ) dp[i][j] += dp[i+1][j-1]+1;

也可以用别的递推方式,比如dp[i][j] = SUM(dp[k][j-1]+1)+1( s[k] == s[j] ,i<=k<j )

可以递推求dp[i][j] = dp[i+1][j] + tmp ;这样时间还是O(n^2);

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<vector>
 7 #include<cstdlib>
 8 #include<set>
 9 using namespace std;
10 const int N = 1000+10;
11 const int Mod = 10007;
12 int dp[N][N];
13 char s[N];
14 int n;
15 int dfs(int l,int r){
16     if (r<l) return 0;
17     if (dp[l][r]) return dp[l][r];
18     if (l == r) return dp[l][r] = 1;
19     dp[l][r] = 0;
20     dp[l][r] +=( dfs(l,r-1)+dfs(l+1,r) - dfs(l+1,r-1) );
21     if (s[l] == s[r]) dp[l][r] += dfs(l+1,r-1)+1;
22     return dp[l][r] %= Mod;
23 }
24 int main(){
25     int T,cas = 0; scanf("%d",&T);
26     while (T--){
27         scanf("%s",s);
28         memset(dp,0,sizeof(dp));
29         n = strlen(s);
30         dfs(0,n-1);
31         printf("Case %d: %d\n",++cas,dp[0][n-1]);
32     }
33     return 0;
34 }
View Code

相关文章: