引用大牛lnmm的思路
设ch[1]..ch[n]表示字符串1至n位,i为左游标,j为右游标 ,则i从n递减,j从i开始递增。
min[i][j]表示i和j之间至少需要插入多少个字符才能对称,初始置全0 ,我们最终需要得到的值是min[1][n]. 则
if(ch[i]==ch[j]) //如果两个游标所指字符相同,向中间缩小范围
min[i][j]=min[i+1][j-1];
else
min[i][j] = 1 + (min[i+1][j]和min[i][j-1]中的较小值); //如果不同,典型的状态转换方程
画个图
i\j 1 2 3 4 5 1 0 * * * * 2 0 0 * * * 3 0 0 * * 4 0 0 * 5 0 0
求右上的三角形即可, 三个方向, 左, 下, 左下, 和算法导论里353页的图思路差不多, 意思不一样而已.
一个自以为比较有意思的空间优化是, 把头顺时针转45度看那个三角形.. 不讲了麻烦, 上代码..
404K 344MS G++
#include <stdio.h> int main() { int n; char a[5010]; scanf("%d",&n); while(getchar()!='\n'); scanf("%s",a); int c[10010]; for(int i=2;i<=2*n;i++) { c[i]=0; } for(int x=1;x<=n-1;x++) for(int i=1;i<=n-x;i++) { int j=i+x; char ai=a[i-1],aj=a[j-1]; if(ai==aj) continue; c[i+j]=c[i+j-1]<c[i+j+1]?c[i+j-1]:c[i+j+1]; c[i+j]++; } printf("%d\n",c[1+n]); return 0; }