zoukankan      html  css  js  c++  java
  • [BZOJ] 1090 [SCOI2003]字符串折叠

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1909  Solved: 1251
    [Submit][Status][Discuss]
    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

    字符串上做区间dp,很像hnoi的玩具取名的感觉。

    虽然len最长只有100,但这不代表二维不能做。
    还是枚举[l,r]的划分点,大区间依赖小区间,缩点思想。
    唯一不同的一点是,更新除了由小区间更新,还可以判断自己是否循环,(KMP也可以做),所幸本题数据不大,暴力判断就行。

    循环的话就是循环节长度+2(括号)+dig(循环次数),dig代表位数。
    更新 SQY大兄弟说判断循环节,只需要判到串长一半,再长一定不优,确实是这样的。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    char s[105];
    int len;
    
    int dig(int x) {return x<=9?1:dig(x/10)+1;}
    
    bool pd(int x,int y,int z) {
        for(int i=1;i<=len;i++){
            for(int j=x+i-1;j+z<=y;j+=z){
                if(s[j]!=s[j+z]) return false;
            }
        }
        return true;
    }
    int f[105][105];
    
    int main() {
        memset(f,0x3f,sizeof(f));
        scanf("%s",s+1);
        len=strlen(s+1);
        for(int i=0;i<=len;i++) f[i][i]=1;
        for(int l=0; l<=len; l++) {
            for(int i=1; i+l<=len; i++) {
                int j=i+l;
                for(int k=1; k<=j-i+1; k++) {
                    if((j-i+1)%k==0&&pd(i,j,k)) f[i][j]=min(f[i][j],2+f[i][i+k-1]+dig((j-i+1)/k));
                }
                for(int k=i; k<j; k++) {
                    f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);
                }
    
            }
        }
        cout<<f[1][len];
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9247396.html

  • 相关阅读:
    建站手册-网站构建:首页
    snort-2.9.7.0源码安装过程
    java实现最大镜像子串
    java实现最大镜像子串
    java实现最大五个数
    java实现最大五个数
    java实现最大五个数
    java实现最大五个数
    java实现最大五个数
    java实现祖冲之割圆法
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9247396.html
Copyright © 2011-2022 走看看