输入一个字符串(全部大写),删去其中某些字符后,使其组成一个回文序列。规定若删去的字符不同,则组成的回文序列不同。求能组成多少中不同的回文序列?
实例:
input:XXY
output:4
input:BAB
output:5
思路:设置两个游标,遍历整个字符串
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 string s; 5 long long ans=0; 6 7 void help(int left, int right, int cnt) 8 { 9 if (left >= right) 10 ans += cnt; //遍历终点,更新结果 11 for (int i = left;i < right;i++) 12 { 13 int j = right; 14 while (j>i) 15 { 16 while (s[i] != s[j] && j>i) j--; 17 if (j == i) 18 break; 19 help(i + 1, j - 1, cnt + j - i); //若找到回文字符,则缩小范围,进行下一轮遍历 20 j--; //注意设置循环增量,否则会进入死循环! 21 } 22 } 23 } 24 25 int main() 26 { 27 cin >> s; 28 help(0, s.size() - 1, 0); 29 cout << ans + s.size() << endl; 30 return 0; 31 }
更新:
动态规划解法:用dp[i][j]表示区间[i,j]中的子回文串的个数
有dp关系式:
if(s[i]==s[j])
dp[i][j]+=dp[i+1][j-1]+1;
else
dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1];
初始状态:dp[i][i]=1