题意:给你一个字符串,问将它变成回文串至少需要再添加多少字母。
思路:将字符串反转,然后求把这两个字符串变成一样的需要再添加多少字母。设dp【i】【j】代表第一个串匹配到位置i,第二个串匹配到位置 j 时需要添加的最少字母,当他们相等的时候,答案就是dp【i-1】【j-1】,否则就是min(dp【i-1】【j】,dp【i】【j-1】)+1。那么最终的答案就是dp【n】【n】/2。因为这题卡空间,所以用滚动数组优化,因为dp【i】【j】只由dp【i-1】【j】和dp【i】【j-1】转移,所以用滚动数组优化是没有问题的。
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 5005;
char a[maxn];
int dp[2][maxn];
int main()
{
int n;
scanf("%d%s",&n,a+1);
for(int i=1;i<=n;i++)dp[0][i] = i;
int cur = 0;
for(int i=1;i<=n;i++)
{
cur^=1;
dp[cur][0] = i;
for(int j=1;j<=n;j++)
{
if(a[i] == a[n-j+1])dp[cur][j] = dp[cur^1][j-1];
else dp[cur][j] = min(dp[cur^1][j],dp[cur][j-1]) + 1;
}
}
cout<<dp[cur][n]/2<<'\n';
return 0;
}