回文字符串(最长上升子序列的变形)

回文字符串
时间限制: 1 Sec   内存限制: 128 MB

题目描述

所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba"。当然,我们给你的问题不会再简单到判断一个字符串是不是回文字符串。现在要求你,给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符串。

输入

第一行给出整数N(0<N<100)
接下来的N行,每行一个字符串,每个字符串长度不超过1000.

输出

每行输出所需添加的最少字符数

样例输入

1

Ab3bd

样例输出

2

来源

开始看到这道题的时候,一时想不出用什么很好的方法来做,看到分类是在动态规划,也大致往这方面想,看了别人的思路,顿时茅塞顿开啊,直接把给定的字符串倒转,然后再和原字符串一起,求他们的最长公共序列,然后再拿字符串的长度减去他们的最长公共序列的长度,得到的就是要添加的最小的字符数,想到了这个地方,这个题目就很好解啦;


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <utility>
#include <set>
#include <bitset>
#include <vector>
#define pi acos(-1.0)
#define inf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3fLL
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
int gcd(int x, int y)
{
    if(y==0)return x;
    return gcd(y, x%y);
}
int n;
char a[1005];
char b[1005];
int dp[1005][1005];
int main()
{
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",a);
        ms(dp,0);
        int l=strlen(a);
        for(int i=0;i<l;i++)
            b[l-i-1]=a[i];
        for(int i=1;i<=l;i++)
        {
            for(int j=1;j<=l;j++)
            {
                if(a[i-1]==b[j-1])
                    dp[i][j]=dp[i-1][j-1]+1;
                else
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }
        int maxn=0;
        for(int i=1;i<=l;i++)
        {
            for(int j=1;j<=l;j++)
            {
                maxn=max(maxn,dp[i][j]);
            }
        }

        printf("%d\n",l-maxn);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41021816/article/details/80410899
今日推荐