题目来源:http://acm.pku.edu.cn/JudgeOnline/problem?id=1159
解题报告:
求一个字符串中至少添加几个字符可以使该字符串变成回文串。也是一道简单的DP,我这里用了备忘录的方法,f[i][j]表示要使字符串的第i个到第j个间的字符串成为回文串至少需要添加的字符的个数,那么有两种情况:
第一种,a[i]=a[j],那么f[i][j]=f[i+1][j-1]
第二种,a[i]!=a[j],那么f[i][j]=min(f[i+1][j], f[i][j-1])+1,
对于f[][],我一开始设了一个f[5001][5001],结果报Memory Limit Exceed,于是,我改用动态数组,另外注意到,f[i][j]中j<i的情况是用不到的,因此重新设定,令f[i][j-i]代表原来的f[i][j],那么最后只需要N+(N-1)+...+1=(N+1)*N/2个数,原来则需要N*N个数。再重新提交就AC了。
#include <iostream> using namespace std; int **f; int min(int a,int b) { return a>b?b:a; } int value(char a[], int begin, int end) { if(begin>end) return 0; if(f[begin][end-begin]!=-1) return f[begin][end-begin]; if(begin==end) f[begin][end-begin]=0; else { if(a[begin]==a[end]) f[begin][end-begin]=value(a,begin+1,end-1); else f[begin][end-begin]=1+min(value(a,begin+1,end),value(a,begin,end-1)); } return f[begin][end-begin]; } int main() { int N; cin >> N; char *a=new char[N]; f=new int *[N]; for(int i=0;i<N;i++) f[i]=new int [N-i]; for(int i=0;i<N;i++) cin >> a[i]; for(int i=0;i<N;i++) { for(int j=i;j<N;j++) { f[i][j-i]=-1; } } cout << value(a,0,N-1) << endl; }
附录:
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 29519 | Accepted: 9874 |
Description
Input
Output
Sample Input
5 Ab3bd
Sample Output
2