【bzoj1068】【SCOI2007】压缩

一道区间dp

f[i][j][0/1]表示[i,j]区间是否加入M,并且之前一位有M的最小长度

可以理解为在第一位之前有一个M

那么就可以转移了。

#include<bits/stdc++.h>
using namespace std;
int f[110][110][2],n;
char s[200];
inline bool check(int l,int r){
    int mid=(l+r)>>1;
    for(int i=1;i<=mid-l+1;i++)if(s[l+i-1]!=s[mid+i])return 0;
    return 1;
}
int main(){
    scanf("%s",s+1);int len=strlen(s+1);
    for(int i=len;i;i--)for(int j=i;j<=len;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+min(f[k+1][j][0],f[k+1][j][1]));
        for(int k=i;k<j;k++)f[i][j][0]=min(f[i][j][0],f[i][k][0]+j-k);
        if((j-i+1)%2==0&&check(i,j))f[i][j][0]=f[i][(i+j)>>1][0]+1;
        if(j-i+1==1)f[i][j][1]=n+1;
        //printf("f[%d][%d][%d]=%d\nf[%d][%d][%d]=%d\n",i,j,1,f[i][j][1],i,j,0,f[i][j][0]);
    }
    printf("%d\n",min(f[1][len][0],f[1][len][1]));
}    

 

posted @ 2017-07-26 16:55  zcysky  阅读(...)  评论(...编辑  收藏