您的位置:首页 > 其它

回文字符串 (动态规划,最长公共子序列)

2015-04-29 20:25 239 查看

回文字符串

时间限制:3000 ms | 内存限制:65535 KB难度:4描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba"。当然,我们给你的问题不会再简单到判断一个字符串是不是回文字符串。现在要求你,给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符串。输入第一行给出整数N(0<N<100)接下来的N行,每行一个字符串,每个字符串长度不超过1000.输出每行输出所需添加的最少字符数样例输入
1
Ab3bd
样例输出
2
刚开始看到这道题,看了一会没看出头绪,然后看人家说是要用动态规划里面的最长公共子序列,可是还是想不出为什么。后来同学同学问我这道题,就仔细的想了想。结果发现还真是。
思路:题目中是要求将字符串补成回文串时最少补充的字符。那么我们可以这样想,我们先有一个回文串,然后故意去掉几个。。。就成了题目中的测试案例。
然后呢,假设去掉的那些字符我们保留为空格,我们想,既然之前是回文的,当我们反转过来背去掉剩下的,然后去掉空格,必然会有些字符还是匹配的,这部分匹配的就是不用动的部分,一个字符串当作模式串,一个当作匹配串,从头到尾匹配,总有一种情况下匹配的字符达到最大,这便是我们把他们变回回文串时不用改动的最大数值,然后根据题意,只要我们拿字符串的总长度减去这个数,便是需要改动的最少个数。也就转化成了求最长公共子序列问题。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
char *reverse( char a[])
{
char *b=new char[1005];
int t=strlen(a);
int i,j;
for(i=t-1,j=0;i>=0;j++,i--){
b[j]=a[i];
}
return b;
}
int dp[1000][1000];
int main()
{
int n;
cin>>n;
while(n--)
{
char a[1005];
cin>>a;
int str = strlen(a);
string b=reverse(a);
//cout<<b<<endl;
for(int i =0;i <= str;i ++){
for(int j =0 ;j <= str; j++){
if(i == 0||j == 0) dp[i][j]=0;
else if(b[i-1] == a[j-1]) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}

/*for(int i = 0; i <= str; i ++){
for(int j = 0;j <= str; j++){
cout<<dp[i][j]<<" ";
}
cout<<endl;
}*/
cout<<str-dp[str][str]<<endl;
}
return 0;
}
对案例:asdfgg 进行的测试。[/code]
看下图,理解最长公共子序列
案例是:ACDDEB和ADC

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: