bzoj1068: [SCOI2007]压缩

题目链接

bzoj1068: [SCOI2007]压缩

题解

这道题对于语文不好的我很不友好啊
啥东西啊这是QAQ,题意理解了半天,还是错的QAQQQQ
f[i][j][0] -> i到j中间没有M,f[i][j][1] -> i到j中有M
f[i][j][0] = min(f[i][k][0] + f[k + 1][j][0] + 1) i到j这一段可以拆成i到k和k+1到j,中间加一个M
f[i][j][t] = min(f[i][k][t] + j - k) 压缩i到k段,后一段不管
f[i][j][t]=min(f[i][(i+j)>>1][t]+1),如果可以分为两串相同的话,从中间劈开压缩加一个R

#include<cstdio> 
#include<cstring> 
#include<algorithm>
 
const int maxn = 57; 
char s[maxn]; 
int ans = 0,dp[maxn][maxn][2] ; 
bool judge(int l,int r) { 
    int len = r - l + 1;
    if(len & 1) return false; 
    for(int i = l;i <= l + r >> 1;++ i) 
        if(s[i] != s[i + len / 2]) return false; 
    return true; 
} 
int dfs(int l,int r,int t) { 
    if(dp[l][r][t] != -1) return dp[l][r][t]; 
    int ret = r - l + 1; 
    if(ret == 1) return ret; 
    if(t) for(int i = l;i < r;++ i) 
                ret = std::min(ret,dfs(l,i,t) + dfs(i + 1,r,t) + 1); 
    for(int i = l;i < r;++ i) ret = std::min(ret,dfs(l,i,t) + r - i); 
    if(judge(l,r)) ret = std::min(ret,dfs(l,(l + r) >> 1,0) + 1); 
    return dp[l][r][t] = ret; 
} 
int main() { 
    scanf("%s",s + 1); 
    int len = strlen(s + 1); 
    memset(dp,-1,sizeof dp); 
    printf("%d\n",dfs(1,len,1)); 
    return 0; 
}
posted @ 2018-05-08 16:56  zzzzx  阅读(168)  评论(0编辑  收藏  举报