转:https://i-blog.csdnimg.cn/blog_migrate/a2c0214765c91ded32ff1791430eac34.png
题意:
给你一串字符串,让你求最少加入几个字符,才能使得这个字符串是个回文串。
做法:
设a[i]是这个字符串,b[i]是这个字符串的逆序串。
那么a[i],b[i]的最长公共子序列就是所求的字符串里拥有的最大的回文串。
然后用总串长减去最大的回文串长度即为所求。
如果直接求的话,势必要开一个5001*5001的数组,铁定MLE。
有一下两种解决方法:
1,开short int型数组
这是poj返回的结果:
2,运用动态数组。
根据dp滚动的过程我们可以知道,dp【i】【j】的值不会与dp[i-2][0.....n]的值有关系。
那么可以把dp[i][j]的值覆盖到dp[i-2][j]上。即dp[i][j]为dp[i%2][j];
poj返回的结果:
对比以上两种方法,显而易见的可以得出2的方法很节约空间,就是耗时略
代码(原)
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <set>
#include <string>
using namespace std;
int main()
{
int w[2][5010];
char a[5010];
char b[5010];
int n;
while(scanf("%d",&n)!=EOF)
{
getchar();
for(int i=1;i<=n;i++)
{
scanf("%c",&a[i]);
b[n-i+1]=a[i];
}
for(int i=0;i<=n;i++) //a的长度为0时
w[0][i]=0;
w[1][0]=0; //a的长度为1时
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i]==b[j])
w[i%2][j]=w[(i-1)%2][j-1]+1;
else
w[i%2][j]=max(w[(i-1)%2][j],w[i%2][j-1]);
}
}
printf("%d\n",n-w[n%2][n]);
}
return 0;
}