IOI 2000的题目 实际上是一道区间dp
我们设dp[i][j]代表字符串中第i个字符到第j个字符得到回文串需要添加的字符数,初始化dp[i][i]为0。这里注意还应该初始化dp[i][i+1],如果s[i]==s[i+1]那么dp[i][i+1]=0,否则=1。接着我们枚举不相邻的两个点,如果两个字符相同那么dp[i][j]就等价于dp[i+1][j-1]。否则就等于这一段去掉首字符在尾加上1与去掉尾字符在头加上1的最小值,状态转移更新即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
string s;
int dp[1010][1010];
int main()
{
cin>>s;
int len=s.size();
// memset(dp,0x3f3f3f3f,sizeof(dp));
for(int i=0;i<len;i++)
{
dp[i][i]=0;
}
for(int i=0;i<len-1;i++)
{
if(s[i]==s[i+1]) dp[i][i+1]=0;
else dp[i][i+1]=1;
}
for(int i=2;i<len;i++)
{
for(int j=0;j+i<len;j++)
{
int k=j+i;
if(s[j]==s[k]) dp[j][k]=dp[j+1][k-1];
else dp[j][k]=min(dp[j+1][k]+1,dp[j][k-1]+1);
}
}
printf("%d",dp[0][len-1]);
return 0;
}