题意:添加尽量少的字符使得s串成为回文串,并输出这样得解。
题解:dp[ i ][ j ]表示i~j串需要添加的最少字符。
当s[ i ]==s[ j ]时,dp[ i ][ j ]=dp[ i +1 ][ j - 1 ];
当s[ i ]! =s[ j ]时,dp[ i ][ j ]=min( dp[ i ][ j ],min(dp[ i+1 ][ j ],dp[ i ][ j - 1 ]+1);
头疼的是打印解。
(1)顺着刷
1 void solve(){ 2 for(int i=0;i<n;i++) { dp[i+1][i]=0; dp[i][i]=0; } 3 4 for(int len=1;len<n;len++){ 5 for(int i=0;i+len<n;i++){ 6 dp[i][j]=INF; 7 int j=i+len; 8 if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1]; 9 else dp[i][j]=min(dp[i][j],min(dp[i+1][j],dp[i][j-1])+1); 10 } 11 } 12 cout<<dp[0][n-1]<<" "; 13 }
(2)逆着刷
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn=1005; 8 9 int n; 10 int dp[maxn][maxn],rec[maxn][maxn]; 11 char s[maxn]; 12 13 void solve(){ 14 memset(dp,0,sizeof(dp)); 15 memset(rec,0,sizeof(rec)); 16 17 for(int i=n-1;i>=0;i--){ 18 for(int j=i+1;j<n;j++){ 19 if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1]; 20 else{ 21 if(dp[i+1][j]>dp[i][j-1]){ 22 dp[i][j]=dp[i][j-1]+1; 23 rec[i][j]=1; 24 } 25 else{ 26 dp[i][j]=dp[i+1][j]+1; 27 rec[i][j]=-1; 28 } 29 } 30 } 31 } 32 cout<<dp[0][n-1]<<" "; 33 } 34 35 void print(int i,int j){ 36 if(i>j) return ; 37 if(i==j) printf("%c",s[i]); 38 else if(rec[i][j]==0){ 39 printf("%c",s[i]); 40 print(i+1,j-1); 41 printf("%c",s[i]); 42 } 43 else if(rec[i][j]==1){ 44 printf("%c",s[j]); 45 print(i,j-1); 46 printf("%c",s[j]); 47 48 } 49 else{ 50 printf("%c",s[i]); 51 print(i+1,j); 52 printf("%c",s[i]); 53 } 54 } 55 56 57 int main() 58 { while(scanf("%s",s)!=EOF){ 59 n=strlen(s); 60 61 solve(); 62 print(0,n-1); 63 cout<<endl; 64 } 65 return 0; 66 }