【洛谷 P4302】 [SCOI2003]字符串摺疊(DP)

題目鏈接
簡單區間dp
\(f[i][j]\)表示\([i,j]\)的最短長度
先枚舉區間,然後在區間中枚舉長度\(k\),看這個區間能不能摺疊成幾個長度爲\(k\)的,如果能就更新答案。

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
char s[110];
int f[110][110], n, num[110];
string p[110][110];
inline int check(int a, int b, int c){
    int d = b - a + 1;
    for(int i = c; i < d; ++i)
        if(s[a + i] != s[a + (i % c)])
            return 0;
    return 1;
}
int main(){
    while(scanf("%s", s + 1) != EOF){
        n = strlen(s + 1);
        for(int i = 1; i <= 9; ++i) num[i] = 1;
        for(int i = 10; i <= 99; ++i) num[i] = 2;
        num[100] = 3;
        for(int i = 1; i <= n; ++i)
            f[i][i] = 1;
        for(int l = 2; l <= n; ++l)
            for(int i = 1; i + l - 1 <= n; ++i){
                int j = i + l - 1;
                f[i][j] = l;
                for(int k = 1; k < l; ++k){
                    f[i][j] = min(f[i][j], f[i][i + k - 1] + f[i + k][j]);
                    if(l % k == 0)
                        if(check(i, j, k))
                            f[i][j] = min(f[i][j], 2 + num[l / k] + f[i][i + k - 1]);
                }
            }
        printf("%d\n", f[1][n]);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章