【测评中的编程题】判断子序列是否为回文序列

输入一个字符串(全部大写),删去其中某些字符后,使其组成一个回文序列。规定若删去的字符不同,则组成的回文序列不同。求能组成多少中不同的回文序列?

实例:

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

posted @ 2018-04-09 23:36  AWC小干  阅读(870)  评论(0编辑  收藏  举报