LCS+滚动数组HDU1513
http://acm.hdu.edu.cn/showproblem.php?pid=1513
给一个字符串,求这个字符串最少增加几个字符能变成回文,如Ab3bd可以增加2个字符变为回文:Adb3bdA。通过这样的结论可以和最长公共子串联系起来(未证明):S和S' (注:S'是S的反串)的最长公共子串其实一定是回文的。这样我们就可以借助lcs来解决该题,即用s的长度减去lcs的值即可。
#include<string.h> #include<stdio.h> short ans[2][5001]; int max(int a,int b) { return a>b?a:b; } int main() { int i,j,len; char a[5001],b[5001]; while(scanf("%d",&len)!=EOF) { gets(a); gets(a); for(i=len-1,j=0;i>=0;i--)b[j++]=a[i]; b[j]='\0'; for(i=0;i<=len;i++) for(j=0;j<=len;j++) ans[i%2][j]=0;//初始化为0 for(i=1;i<=len;i++) for(j=1;j<=len;j++) { if(a[i-1]==b[j-1])//如果都相等,两个指针都前移并将该处的子串长度加一 ans[i%2][j]=1+ans[(i-1)%2][j-1]; else ans[i%2][j]=max(ans[i%2][j-1],ans[(i-1)%2][j]);//否则保留两个子串前个阶段最大的那个 } printf("%d\n",len-ans[len%2][len]); } return 0; }
另外,滚动数组中不可两者都滚动,因为这样都导致两维的结合错误,得到错误结果,所以只滚动一个维就可以