• P4302 [SCOI2003]字符串折叠


    我居然在第一个最优解?

    (f_{i,j})([i,j])中的最短长度。

    [f_{i,j} = min(min limits_{i le k < j} {f_{i,k} + f_{k + 1,j}},min limits_{i le k < j \ s[i,k]是s[i,j]的循环节} {f_{i,k} + LEN(L) + 2}) ]

    其中(LEN(x))(x)的位数,(L)为循环节数。

    时间复杂度(O(n ^ 4))?显然不是。

    (s[i,k])的长度不整除(s[i,j])的长度时,显然不成立,剪枝。

    #include <bits/stdc++.h>
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const int N = 110;
    char s[N];
    int f[N][N];
    int n;
    
    int check(int l, int r, int R)
    {
        int k = l;
        int cnt = 0;
        for (int i = l; i <= R; i++)
        {
            if (k > r)
                k = l, cnt++;
            if (s[k] != s[i])
                return 0;
            ++k;
        }
        return cnt;
    }
    
    int Getlen(int x)
    {
        int cnt = 0;
        while (x)
        {
            cnt++;
            x /= 10;
        }
        return cnt;
    }
    
    int main(void)
    {
        scanf("%s", s + 1);
        n = strlen(s + 1);
        // printf("%d
    ", n);
        // for (int i = 1; i <= n; i++)
        // {
        //     cout << s[i];
        // }
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                f[i][j] = (i == j) ? 1 : inf;
            }
        }
        // printf("n = %d
    ", n);
        for (int len = 2; len <= n; len++)
        {
            for (int i = 1, j = i + len - 1; i <= n - len + 1; i++, j++)
            {
                // printf("i = %d,j = %d,%d
    ", i, j, i <= n);
                for (int k = i; k < j; k++)
                {
                    f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j]);
                }
                for (int k = i; k < j; k++)
                {
                    int L = (k - i + 1);
                    if (len % L != 0)
                        continue;
                    int ck = check(i, k, j);
                    // printf("check(%d,%d,%d) = %d
    ", i, k, j, ck);
                    if (ck > 0)
                    {
                        f[i][j] = min(f[i][j], f[i][k] + Getlen(len / L) + 2);
                    }
                }
            }
        }
        printf("%d
    ", f[1][n]);
        return 0;
    }
    
  • 相关阅读:
    前端基础 — BOM和DOM
    JavaScript概述
    前端知识 — HTML内容、CSS基础
    数据库MySQL
    jquery ajax() 方法使用
    移动端自适应的问题及解决
    jquery appendTo 和 append 的用法
    css 截取文字
    电脑模拟手机工具
    jquery 旋转插件jqueryrotate
  • 原文地址:https://www.cnblogs.com/luyiming123blog/p/P4302.html
Copyright © 2020-2023  润新知