• 【BZOJ 1090】[SCOI2003]字符串折叠


    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))

    又是区间型DP,然后又没推出方程,果真我的DP不是一般的弱啊,hhh

    f[i][j]表示最短长度

    f[i][j]=min(f[i][k]+f[k+1][j])//不解释

    f[i][j]=min(f[i][k]+cal((j-k)/(k-i+1)+1)) //若j-k是k-i+1的n倍。。。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 int f[110][110];
     6 char s[110];
     7 bool judge(int l,int r,int ll,int rr){
     8     if((r-l+1)%(rr-ll+1)) return 0;
     9     for(int i=l;i<=r;i++) if(s[i]!=s[(i-l)%(rr-ll+1)+ll]) return 0;
    10     return 1;
    11 }
    12  
    13 int calc(int x){
    14     int t=0;
    15     while(x){
    16         t++; x/=10;
    17     }
    18     return t;
    19 }
    20  
    21 int dp(int l,int r){
    22     if(l==r) return 1;
    23     if(f[l][r]!=-1) return f[l][r];
    24     int tmp=(r-l+1);
    25     for(int i=l;i<r;i++) tmp=min(tmp,dp(l,i)+dp(i+1,r));
    26     for(int i=l;i<r;i++)
    27     if(judge(i+1,r,l,i))
    28     tmp=min(tmp,dp(l,i)+2+calc((r-i)/(i-l+1)+1));
    29     f[l][r]=tmp;
    30     return tmp;
    31 }
    32  
    33 int main(){
    34     scanf("%s",s+1);
    35     int len=strlen(s+1);
    36     memset(f,-1,sizeof(f));
    37     printf("%d",dp(1,len));
    38 }
  • 相关阅读:
    minecraft我的世界汇总网站
    扫雷网页版
    扫雷模型(非完全一样)
    设计模式-策略模式
    hadoop(2)hadoop配置
    hadoop(1)入门
    Openssl
    加密解密
    信息安全通信
    Web
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5215703.html
Copyright © 2020-2023  润新知