链接:http://poj.org/problem?id=1159
题意:已知一个串,求至少插入几个字符,使得该串成为回文串。
一开始自己瞎搞了一通,几经周折,还是WA。然后就看discuss了。
说说思路吧(当然是看人家的)。此题的本质:假设原串为S,求其与逆序串S'的最长公共子序列,然后再用原串的长度n-最大长公共子序列长度
此即为所求最少需要添加到字符的个数。
这个题还有一个地方要注意的是,定义 int dp[5001][5001]会抄内存,然后要用short(这个short是什么东西我还真不知道。。)定义;
还有一个解决办法是用滚动数组。。这又是什么。。。还得再学习啊
这个题代码写起来倒是挺简单的,也算是练了一下LCS。恩。这一题以后还得来补充说明。
#include<stdio.h>
#include<string.h>
#define MAXN 5005
short dp[MAXN][MAXN];
int main()
{
int n,i,j;
char str[MAXN],ptr[MAXN];
while(scanf("%d",&n)==1)
{
scanf("%s",str);
for(i=0;i<n;i++)
ptr[n-i-1]=str[i];//原串的逆序
for(i=0;i<=n;i++)//初始化为0
dp[i][0]=0;
for(i=0;i<=n;i++)
dp[0][i]=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(str[i]==ptr[j])
dp[i+1][j+1]=1+dp[i][j];//因为字符串下标从0开始,所以从dp[1][1]开始
else if(dp[i][j+1]>=dp[i+1][j])
dp[i+1][j+1]=dp[i][j+1];
else
dp[i+1][j+1]=dp[i+1][j];
}
printf("%d\n",n-dp[n][n]);
}
return 0;
}