明显是个区间dp,但是我区间dp就是个渣。。。
f[i][j]表示区间i到j最短的字符长度;假设前面加了个M,所以初始化f[i][i]=2;当然最开始是不算M的,所以f[1][1]=1;然后就可以区间dp了。 f[i][j]=min{f[i][j-1]+1};//从上一个加一更新过来(如果不存在重合的话)
if(a[i]==a[j]&&check(i,j))//判断是否有重合部分
f[i][j+j-i-1]=min(f[i][j+j-i-1],f[i][j-1]+1);//重合部分用R代替,所以要+1.注意好下标,最后再用一个dp合并就可以了。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define pos(i,a,b) for(int i=(a);i<=(b);i++) char a[100],b[100]; int n; int f[100][100]; int check(int i,int j) { pos(k,1,j-i-1) { if(a[i+k]!=a[j+k]) return 0; } return 1; } int main() { memset(f,50,sizeof(f)); scanf("%s",&b); n=strlen(b); pos(i,1,n) a[i]=b[i-1]; //cout<<n; pos(i,1,n) f[i][i]=2; f[1][1]=1; pos(i,1,n) pos(j,i+1,n) { f[i][j]=min(f[i][j-1]+1,f[i][j]); if(a[i]==a[j]&&check(i,j)) f[i][j+j-i-1]=min(f[i][j+j-i-1],f[i][j-1]+1); } pos(i,1,n) pos(j,i+1,n) pos(k,i,j-1) f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]); cout<<f[1][n]; //while(1); return 0; }