这是一道基本的动态规划题,可惜我连一个正确的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), mazheng19891019@gmail.com
* 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), mazheng19891019@gmail.com
* 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;
}