hdu 4632 Palindrome subsequence
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4632
大意:求出一个串的不同的回文子序列的个数
思路:首先是回文子序列,不是子串;考虑动态规划,状态表示:f[s][e]表示区间[s,e]内有所少个回文子序列,那么转移就是:
f[s][e] = f[s+1][e] + f[s][e-1] - f[s+1][e-1],因为[s+1,e]和[s,e-1]会有重复的部分(容斥原理);
另外,如果ch[s] = ch[e],那么可以首位两个字符可以和内部的串组成新的回文串,加上其本身("ch[s]ch[e]"也是回文串),故还需要加上
f[s][e] += f[s+1][e-1]+1,这样一来,状态转移是完备的
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 using namespace std; 5 const int p = 10007; 6 int f[1001][1001]; 7 int main() 8 { 9 int t; scanf("%d\n", &t); 10 for (int k=1; k<=t; k++) 11 { 12 string s; cin >> s; 13 int n = s.size(); 14 memset(f, 0, sizeof(f)); 15 for (int i=0; i<n; i++) f[i][i] = 1; 16 for (int i=1; i<n; i++) 17 for (int j=0; j<n-i; j++) 18 { 19 if (s[j] == s[i+j]) f[j][i+j] += (f[j+1][i+j-1]+1) % p; 20 f[j][i+j] += (f[j+1][i+j]+f[j][i+j-1]-f[j+1][i+j-1]+p) % p; 21 } 22 printf("Case %d: %d\n", k, f[0][n-1]%p); 23 } 24 //system("pause"); 25 return 0; 26 }