POJ Palindrome

一、分析

题目意思:给你个字符串。求最少须要加入几个字符使它变成一个回文字符串。
本来想着硬来,后来发现太麻烦了,然后才知道,这个题可以看作是最长公共子序列的动态规划题(!),将字符串和字符串的逆向的最长公共子序列求出来,最后再用总长度减去即可。

而最长公共子序列最近正好有了解:

我们观察两个字符串,如果他们最后一个字符相同,则他们的LCS(最长公共子序列简写)就是两个字符串都去掉最后一个字符的LCS再加一。因为最后一个字符相同,所以最后一个字符是他们的子序列,把他去掉,子序列就少了一个,所以他们的LCS是他们去掉最后一个字符的字符串的LCS再加一。如果他们最后一个字符不相同,那他们的LCS就是X去掉最后一个字符与Y的LCS,或者是X与Y去掉最后一个字符的LCS,是他们两个中较长的那一个。写成数学公式就是:
在这里插入图片描述
所以根据这个就可以很容做出这题了。

二、代码

代码如下(示例):

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 5001
int n;
int i,j;
char s[MAX];
short dp[MAX+1][MAX+1];
int max1(int a,int b)
{
	return a>b?a:b;
}
int main()
{
    while(scanf("%d",&n)==1)
    {
        getchar();
        for(i=0;i<n;i++)
        {
            scanf("%c",&s[i]);
        }
        for (i=0;i<n;i++)//第一行,第一列都为0
        {
            dp[0][i]=0;
            dp[i][0]=0;
	    }
	    for (i=0;i<n;i++)
        {
            for (j=0;j<n;j++)
        {
    	if (s[i]==s[n-1-j])
				dp[(i+1)][j+1]=dp[i][j]+1;
			else
				dp[(i+1)][j+1]=max1(dp[i][j+1],dp[(i+1)][j]);
        }
        }
		printf("%d\n",n-dp[n][n]);

    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值