51nod 1092 回文字符串【LCS】

1092 回文字符串

基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题
收藏
关注
回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。每个字符串都可以通过向中间添加一些字符,使之变为回文字符串。
例如:abbc 添加2个字符可以变为 acbbca,也可以添加3个变为 abbcbba。方案1只需要添加2个字符,是所有方案中添加字符数量最少的。
 
Input
输入一个字符串Str,Str的长度 <= 1000。
Output
输出最少添加多少个字符可以使之变为回文字串。
Input示例
abbc
Output示例
2
[分析]:求逆串与原串的最长公共子序列(可不连续),结果就为字符串长度-最长公共子序列长度。
[代码]:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1010;
string a,b;
int dp[maxn][maxn];
int main(){
    cin>>b;
    int n=b.size();
    a=b;
    reverse(b.begin(),b.end());
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            if(a[i-1]==b[j-1]) //这里为什么要用i-1,j-1,因为str中的下标从0开始
                 dp[i][j]=dp[i-1][j-1]+1;
            else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
        }
    }
    cout<<n-dp[n][n]<<endl;
    return 0;
}
输出长度

 



#include<cstring>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
char a[1010],b[1010];
int f[1010][1010];
string s;
int main()
{
    scanf("%s",a+1);
    scanf("%s",b+1);
    int n=strlen(a+1);
    int m=strlen(b+1);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(a[i]==b[j]) f[i][j]=f[i-1][j-1]+1;
            else f[i][j]=max(f[i-1][j],f[i][j-1]);
        }
    int i=n,j=m;
    while(i && j)
    {
        if(a[i]==b[j])
        {
            s+=a[i];
            i--;
            j--;
        }
        else if(f[i][j]==f[i-1][j]) i--;
        else j--;
    }
    int len=s.length();
    for(int i=len-1;i>=0;i--)
        printf("%c",s[i]);
}
输出字符串

 

posted @ 2018-03-23 08:34  Roni_i  阅读(290)  评论(0编辑  收藏  举报