这是一道基本的动态规划题,可惜我连一个正确的dp方法都没想出来。惭愧。
一直认为DP是几种编程思想里最难掌握的,“状态转移式子”很难总结出来。DP真的应该多练一练。
这道题的两个思路:
思路1:设min[i][j]表示字符串str[i~j]转化为对称串所需添加的最小字符数,则
当str[i]==str[j]时,min[i][j]=min[i+1][j-1];
否则,min[i][j]=1+Min(min[i+1][j],min[i][j-1])
思路2:把str转化为对称串所需添加的最小字符数==strlen(str)-strlen(str与它的反序串reverse_str的最长公共子序列)
求最长公共子序列的方法:
设dp[i][j]表示字符串str1[0~i]与字符串str2[0~j]的最长公共子序列,则
当str1[i]==str2[j]时,dp[i][j]=dp[i-1][j-1]+1;
否则,dp[i][j]=Max(dp[i-1][j],dp[i][j-1]);
代码如下:
/* * ===================================================================================== * * Filename: 1159.c * * Description: * * Version: 1.0 * Created: 2012年05月16日 11时57分38秒 * Revision: none * Compiler: gcc * * Author: MaZheng (blog.csdn.net/mazheng1989), [email protected] * Company: Dalian University Of Technology * * ===================================================================================== */ #include<stdio.h> #define Max_Len 5005 /* */ #define Min(a,b) ((a)>(b)?(b):(a)) /* */ //please declare parameters here. short min[Max_Len][Max_Len]; int N; char str[Max_Len]; //please declare functions here. int main() { if(freopen("input.txt","r",stdin)==NULL) perror("Can not open the input file!"); //input your ... scanf("%d\n",&N); scanf("%s",str+1); // puts(str+1); int i,j; for(i=N;i>0;i--) { for(j=1;j<=N;j++) { // printf("%c %c\n",str[i],str[j]); if(i==j) { continue; } if(str[i]==str[j]) { min[i][j]=min[i+1][j-1]; } else { min[i][j]=1+Min(min[i+1][j],min[i][j-1]); } } } printf("%d\n",min[1][N]); return 0; }
/* * ===================================================================================== * * Filename: 1159a.c * * Description: * * Version: 1.0 * Created: 2012年05月16日 12时52分15秒 * Revision: none * Compiler: gcc * * Author: MaZheng (blog.csdn.net/mazheng1989), [email protected] * Company: Dalian University Of Technology * * ===================================================================================== */ #include<stdio.h> #define Max(a,b) ((a)>(b)?(a):(b)) /* */ #define Max_Len 5005 /* */ short dp[Max_Len][Max_Len]; int N; char str1[Max_Len],str2[Max_Len]; //please declare parameters here. //please declare functions here. int main() { if(freopen("input.txt","r",stdin)==NULL) perror("Can not open the input file!"); //input your ... scanf("%d\n",&N); scanf("%s",str1+1); int i,j; for(i=1;str1[i];i++) { str2[N+1-i]=str1[i]; } for(i=1;i<=N;i++) { for(j=1;j<=N;j++) { if(str1[i]==str2[j]) { dp[i][j]=dp[i-1][j-1]+1; } else { dp[i][j]=Max(dp[i-1][j],dp[i][j-1]); } } } printf("%d\n",N-dp[N][N]); return 0; }