题意:给定一个字符串,求添加最少的字母使得该串是回文串。
思路:区间dp+记忆化搜索。dp[i][j]为区间的最小添加数,那么dp[i][j]=min(dp[i+1][j],dp[i][j-1])+1;相等时则为dp[i+1][j-1];
code:
#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=1005;
char s[N];
int n,dp[N][N];
int dfs(int i,int j)
{
if (i>j||i==j) return dp[i][j]=0;
if (dp[i][j]!=INF) return dp[i][j];
int& ans=dp[i][j];
if (s[i]==s[j]) ans=dfs(i+1,j-1);
ans=min(ans,min(dfs(i+1,j),dfs(i,j-1))+1);
return dp[i][j];
}
void print(int i,int j)
{
if (i>j) return;
if (i==j) {printf("%c",s[i]);return;}
if (s[i]==s[j])
{
printf("%c",s[i]);
print(i+1,j-1);
printf("%c",s[i]);
} else if (dp[i][j]==dp[i+1][j]+1){
printf("%c",s[i]);
print(i+1,j);
printf("%c",s[i]);
}else {
printf("%c",s[j]);
print(i,j-1);
printf("%c",s[j]);
}
}
int main()
{
while (~scanf("%s",s))
{
int n=strlen(s);
memset(dp,INF,sizeof(dp));
dfs(0,n-1);
printf("%d ",dp[0][n-1]);
print(0,n-1);
puts("");
}
}