zoukankan      html  css  js  c++  java
  • B1090 [SCOI2003]字符串折叠 区间dp

    又一道区间dp,和上一篇类似,但是比他简单,这个只有两种转移方法,不是很复杂。直接判断是否为重复的串就行。

    题干:

    Description
    折叠的定义如下: 1. 一个字符串可以看成它自身的折叠。记作S  S 2. X(S)是X(X>1)个S连接在一起的串的折叠。记作X(S)  SSSS…S(X个S)。 3. 如果A  A’, BB’,则AB  A’B’ 例如,因为3(A) = AAA, 2(B) = BB,所以3(A)C2(B)  AAACBB,而2(3(A)C)2(B)AAACAAACBB 给一个字符串,求它的最短折叠。例如AAAAAAAAAABABABCCD的最短折叠为:9(A)3(AB)CCD。
    Input
    仅一行,即字符串S,长度保证不超过100。
    Output
    仅一行,即最短的折叠长度。
    Sample Input
    NEERCYESYESYESNEERCYESYESYES
    Sample Output
    14
    HINT
    一个最短的折叠为:2(NEERC3(YES))
    Source

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    char s[1100];
    int f[1100][1100],n,l;
    bool get(int x1,int y1,int x2,int y2)
    {
        if((y2 - x1 + 1) % (y1 - x1 + 1) != 0)
        return false;
        int len = y1 - x1 + 1;
        duke(i,x2,y2)
        {
            if(s[i] != s[i - len])
            return false;
        }
        return true;
    }
    int cal(int k)
    {
        int cnt = 0;
        while(k)
        {
            cnt++;
            k /= 10;
        }
        return cnt;
    }
    int main()
    {
        memset(f,0x3f,sizeof(f));
        scanf("%s",s + 1);
        n = strlen(s + 1);
        duke(i,0,n)
        f[i][i] = 1;
        duke(l,1,n - 1)
        {
            duke(i,1,n - 1)
            {
                int j = i + l;
                f[i][j] = (j - i + 1);
                duke(k,i,j - 1)
                {
                    if(!get(i,k,k + 1,j))
                        f[i][j] = min(f[i][j],f[i][k] + f[k + 1][j]);
                    else
                        f[i][j] = min(f[i][j],f[i][k] + 2 + cal((l + 1) / (k - i + 1)));
                }
            }
        }
        printf("%d
    ",f[1][n]);
        return 0;
    }
  • 相关阅读:
    Qt 交换Layout中的QWidget控件位置
    霍夫变换(Hough)
    图像傅里叶变换
    通俗讲解:图像傅里叶变换
    傅里叶分析之掐死教程(完整版)
    一幅图弄清DFT与DTFT,DFS的关系
    Qt 实现简单的TCP通信
    Qt 基于TCP的Socket编程
    Socket原理讲解
    科研相机选择:sCMOS还是CCD?
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9726965.html
Copyright © 2011-2022 走看看