回文字符串 (动态规划,最长公共子序列)
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 进行的测试。
看下图,理解最长公共子序列
案例是:ACDDEB和ADC
相关文章推荐
- 动态规划--最长公共子序列
- 动态规划-最长公共子序列
- 动态规划解最长公共子序列问题
- DP动态规划——hdu 1008 Common Subsequence(最长公共子序列)
- 最长公共子序列问题的动态规划解法
- 动态规划解最长公共子序列问题
- 最长公共子序列求解:递归与动态规划方法
- 动态规划 CSU - 1060 Nearest Sequence(3个字符串的最长公共子序列)
- 动态规划 最长公共子序列 过程图解(转载至http://blog.csdn.net/hrn1216/article/details/51534607#quote)
- 动态规划--最长公共子序列
- 动态规划-最长公共子序列
- 动态规划--最长公共子序列
- 动态规划之最长公共子序列(LCS)
- 动态规划:最长公共子序列与最长公共子串
- 动态规划-最长公共子序列的备忘录算法
- 最长公共子序列求解:递归与动态规划方法
- 动态规划之最长公共子序列
- 动态规划 最长公共子序列过程分析
- NYOJ题目36-最长公共子序列(经典动态规划题)
- 动态规划解最长公共子序列问题