/************************************************************** Problem: 1068 User: lxy8584099 Language: C++ Result: Accepted Time:20 ms Memory:900 kb ****************************************************************/ /* 胡乱DP hash f i,j,k 表示 i~j 有没有M的最小长度 默认在i-1处有一个M 这样由子问题转到最后的问题 1-1即0处就存在一个M 这样操作不影响转移 */ #include<cstdio> #include<cstring> #define ll unsigned long long using namespace std; const int N=100; ll B=233,base[N]={1},s[N]; char str[N]; int f[N][N][2],n; int min(int a,int b) {return a>b?b:a;} ll hash(int l,int r) { return s[r]-s[l-1]*base[r-l+1]; } int main() { memset(f,0x3f,sizeof(f)); scanf("%s",str+1); n=strlen(str+1); for(int i=1;i<=n;i++) { base[i]=base[i-1]*B; s[i]=s[i-1]*B+str[i]; } for(int i=n;i>=1;i--) for(int j=i;j<=n;j++) { f[i][j][0]=f[i][j][1]=j-i+1; for(int k=i;k<j;k++) f[i][j][1]=min(f[i][j][1], min(f[i][k][0],f[i][k][1])+1 // 这个1是k+1 -1处 默认的 M +min(f[k+1][j][1],f[k+1][j][0])); // 可能有的就是任何情况的最小值 for(int k=i;k<j;k++) f[i][j][0]=min(f[i][j][0],f[i][k][0]+j-k); // 这里不是 f[i][k][0]+f[k+1][j][0] 因为k往后走 一定能包括此方案 // 所以把后面的默认为一个一个 dou 起来的 // 不可能有的就只能由不可能转过来 int mid=(i+j)>>1; if((j-i+1)%2==0&&hash(i,mid)==hash(mid+1,j)) f[i][j][0]=f[i][mid][0]+1; // 需要一个R //能缩就缩 } printf("%d\n",min(f[1][n][0],f[1][n][1])); return 0; }
bzoj 1068: [SCOI2007]压缩
猜你喜欢
转载自www.cnblogs.com/lxy8584099/p/10313198.html
今日推荐
周排行