题目大意
给出一个串的长度及该串内容,可以在任意位置插入一个字符,求最少的插入数字,使得串编程回文串.
回文串及从左向右和从右向左读相同.
例如.
aaaacbbbb是回文串
aaab不是回文串我们可以给最前面插入b使得原串变为baaab这个回文串
我的思路.
1.如果该串为空串,或者长度为一,该串是回文串.
2.如果有字符串,a[o...n-1],(0<=l,r<n)如果从l-r之
1可能是l-r对称回文(如果a[l]==a[r]),在匹配[l+1,r-1]这个串
2.l,给r处添加字a[l]和l位置匹配,在匹配[l,r-1]这个串
3l处添加字符a[r],和r位置匹配,在匹配[l+1,r]这个串
3.用以上方法加上备忘录d[l][r]来记录算过的串的最少插入数目
d[l][r]记录从l...r匹配插入的最少字符,问题d[0][n-1]
if(a[l]==a[r]) dd[l][r]=d[l+1][r+1];
else dd[l][r]=max(dd[l+1][r],dd[l][r-1])+1;
备忘录开成short,否则内存超,
险过得的代码.
/*Source Code
Problem: 1159 User:
Memory: 49652K Time: 1782MS
Language: GCC Result: Accepted
Source Code*/
/*插入最少的数字是原来数组成回文串*/
#include <stdio.h>
#include <string.h>
short dd[5001][5001];
char str[5002]="";
int min(int a,int b) {
return a<b?a:b;
}
int f(int l,int r){
if(l>=r) return 0;
else if(dd[l][r]>=0) return dd[l][r];//已经计算出来答案
else{
if(str[l]==str[r])
dd[l][r]=f(l+1,r-1);
else
dd[l][r]=min(f(l+1,r),f(l,r-1))+1;
return dd[l][r];
}
}
int main(){
int n;
scanf("%d",&n);
scanf("%s",str);
memset(dd,-1,sizeof(dd));
printf("%d\n",f(0,n-1));
return 0;
}