HDU-4632 Palindrome subsequence
题意:给定一个字符串,长度最长为1000,问该串有多少个回文子串。
分析:设dp[i][j]表示从 i 到 j 有多少个回文子串,则有动态规划方程:
str[i] != str[j]:dp[i][j] = dp[i+1][j] + dp[i][j-1] - dp[i+1][j-1];
str[i] = str[j]:dp[i][j] = dp[i+1][j] + dp[i][j-1] + 1.
#include <cstdlib> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int mod = 10007; const int N = 1005; char str[N]; int f[N][N]; int solve(int len) { memset(f, 0, sizeof (f)); for (int i = 0; i < len; ++i) { f[i][i] = 1; } for (int k = 2; k <= len; ++k) { // 枚举长度 for (int i = 0, j; i < len && (j=i+k-1) < len; ++i) { if (str[i] == str[j]) { f[i][j] = (f[i][j-1] + f[i+1][j] + 1) % mod; } else { f[i][j] = ((f[i][j-1] + f[i+1][j] - f[i+1][j-1]) % mod + mod) % mod; } } } return f[0][len-1]; } int main() { int T, ca = 0; scanf("%d", &T); while (T--) { scanf("%s", str); int len = strlen(str); printf("Case %d: %d\n", ++ca, solve(len)); } return 0; }