BZOJ1068_压缩_KEY
区间DP,设f[i][j][0/1]为i~j区间的压缩情况,1表示在插入了一个M。
code:
/************************************************************** Problem: 1068 User: yekehe Language: C++ Result: Accepted Time:56 ms Memory:1308 kb ****************************************************************/ #include <cstdio> #include <string> #include <iostream> #include <algorithm> using namespace std; string S; int f[51][51][2]; int check(int i,int j) { int mid=i+j>>1; for(int k=0;k<=mid-i;k++) if(S[i+k]!=S[mid+1+k])return 0; return 1; } int main() { cin>>S; int N=S.size(); for(int i=N-1;i>=0;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][0]=min(f[i][j][0],f[i][k][0]+j-k);//不加M直接取 for(int k=i;k<j;k++) f[i][j][1]=min(min(f[i][k][0],f[i][k][1])+min(f[k+1][j][0],f[k+1][j][1])+1,f[i][j][1]);//加了M的情况枚举k在哪里加入M if(!((j-i+1)&1)&&check(i,j)){ f[i][j][0]=min(f[i][j][0],f[i][i+j>>1][0]+1);//这里之所以是0,是因为默认前段为起点,即默认有M存在。(类似于i~j区间为一个单独的串) } if(!(i^j))f[i][j][1]=N+1;//i==j } printf("%d",min(f[0][N-1][0],f[0][N-1][1])); return 0; }