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

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

实例:

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

转载于:https://www.cnblogs.com/xiao-gan/p/8764276.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值