HDU 4632 Palindrome subsequence
dp[x][y]表示区间[x,y]构成回文串的方案数。
若str[x]==str[y],dp[x][y]=dp[x+1][y]+dp[x][y-1]-dp[x+1][y-1]+(dp[x+1][y-1]+1)=dp[x+1][y]+dp[x][y-1]+1。
若str[x]!=str[y],dp[x][y]=dp[x+1][y]+dp[x][y-1]-dp[x+1][y-1]。
1 #include<cstdio> 2 #include<cstring> 3 #define MAXN 1010 4 #define MOD 10007 5 char str[MAXN]; 6 int dp[MAXN][MAXN]; 7 int dfs(int x, int y) { 8 if (dp[x][y] == -1) { 9 if (str[x] != str[y]) { 10 dp[x][y] = dfs(x + 1, y) + dfs(x, y - 1) - dfs(x + 1, y - 1); 11 } else { 12 dp[x][y] = dfs(x + 1, y) + dfs(x, y - 1) + 1; 13 } 14 } 15 dp[x][y] %= MOD; 16 return dp[x][y]; 17 } 18 int main() { 19 int T; 20 int ca = 1; 21 int len; 22 int i; 23 scanf("%d", &T); 24 while (T--) { 25 memset(dp, -1, sizeof(dp)); 26 scanf(" %s", str); 27 len = strlen(str); 28 for (i = 0; i < len; i++) { 29 dp[i][i] = 1; 30 } 31 for (i = 1; i < len; i++) { 32 if (str[i] == str[i - 1]) { 33 dp[i - 1][i] = 3; 34 } else { 35 dp[i - 1][i] = 2; 36 } 37 } 38 printf("Case %d: %d\n", ca++, (dfs(0, len - 1) + MOD) % MOD); 39 } 40 return 0; 41 }