[SCOI2007]压缩

Posted ympc2005

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SCOI2007]压缩相关的知识,希望对你有一定的参考价值。

区间dp

设f[i][j][0/1]表示i~j这一段中无/可能有 M 的最小长度

讨论是否整段折叠,以即插入M的位置可以得到转移方程

f[i][j][0] = min(f[i][k][0] + j - k)

f[i][j][1] = min(min(f[i][k][0/1]) + min(f[k + 1][j][0/1] + 1))

if i~mid == mid + 1~j  f[i][j][0] = min(f[i][mid][0] + 1)

技术图片
#include<bits/stdc++.h>
using namespace std;

char s[105];
int f[105][105][2], n;

bool check(int l, int r) {
    int mid = (l + r)/2, len = r - l + 1;
    if(len%2 != 0) return 0;
    for(int p = l; p <= mid; p++)
        if(s[p] != s[p + len/2]) return 0;
    return 1;
}

int main() {
    cin>>(s + 1);
    n = strlen(s + 1);
    for(int L = 1; L <= n; L++) {
        for(int i = 1; i + L - 1 <= n; i++) {
            int j = i + L - 1;
            f[i][j][0] = f[i][j][1] = L;
            for(int k = i; k < j; k++)
                f[i][j][0] = min(f[i][j][0], f[i][k][0] + j - k);
            for(int k = i; k < j; k++)
                f[i][j][1] = min(f[i][j][1], min(f[i][k][1], f[i][k][0]) + min(f[k + 1][j][0], f[k + 1][j][1]) + 1);
            if(check(i, j)) f[i][j][0] = min(f[i][j][0], f[i][i + L/2 - 1][0] + 1);
        }
    }
    cout<<min(f[1][n][0], f[1][n][1])<<endl;
    return 0;
}
View Code

以上是关于[SCOI2007]压缩的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1068: [SCOI2007]压缩

SCOI2007压缩

压缩[SCOI2007]

BZOJ 1068[SCOI2007]压缩

Luogu 2470 [SCOI2007]压缩

bzoj1068: [SCOI2007]压缩