zoukankan      html  css  js  c++  java
  • [SCOI2003]字符串折叠 (区间DP)

    题目描述

    折叠的定义如下:

    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。

    输入输出格式

    输入格式:

    仅一行,即字符串S,长度保证不超过100。

    输出格式: 

    仅一行,即最短的折叠长度。

    输入输出样例

    输入样例#1: 
    NEERCYESYESYESNEERCYESYESYES
    输出样例#1: 
    14

    说明

    一个最短的折叠为:2(NEERC3(YES))

    Solution

    这道题属于很典型的区间DP.

    状态定义:

    f[ i ][ j ] 表示从i 到 j 的最小长度.

    前导状态:

    f [ i ][ j ] 初始化为原长 j - i +1.

    f [ i ][ k ] 和 f[ k+1 ][ j ] 枚举断点并且更新.

    如果要实现合并操作的话.

    我们枚举的两个区间要满足几个条件:

    1. 后面 的区间长度要整除前面合并的第一项长度 (因为合并都是从前面开始所以只需考虑后区间被前区间合并)

    2. 后面的区间每一段都与其相同.

    对于这个,我们直接暴力即可实现.

    然后在 hzwer 学长那里学了一个高级的枚举. 无需担心区间边界问题 ! 递归实现 !

    代码

    #include<bits/stdc++.h>
    using namespace std;
    char ch[101];
    int f[101][101];
    bool vich[101][101];
    bool judge(int l,int r,int cl,int cr)
    {
             if((r-l+1)%(cr-cl+1)!=0) return 0;
             for(int i=l;i<=r;i++)
             if(ch[i]!=ch[(i-l)%(cr-cl+1)+cl]) return 0;
             return 1;
    }
    int cal(int x)
    {int ans=0; while(x%10!=0){ans++;x/=10;}return ans;}
    //cal 为合并后数字的长度
    int ans(int l,int r)
    {
        if(vich[l][r])return f[l][r]; 
        vich[l][r]=1; 
        f[l][r]=r-l+1;
       //初始化为其长度.
        for(int i=l;i<r;i++)
        {
            f[l][r]=min(f[l][r],ans(l,i)+ans(i+1,r));
            if(judge(i+1,r,l,i))
            f[l][r]=min(f[l][r],ans(l,i)+2+cal((r-i)/(i-l+1)+1));
        }
        return f[l][r];
    } 
    int main()
    {
        scanf("%s",ch);
        cout<<ans(0,strlen(ch)-1)<<endl;
    }
  • 相关阅读:
    badblocks 检查硬盘是否有坏道
    IE兼容性开发的笔记
    Linux下设置ip和主机名进行绑定
    netty httpserver
    netty websocket协议开发
    OAuth2.0和SSO授权的区别
    window.location.href跳转问题2
    修改密码,验证两次输入是否相同,相同才能提交
    (2)集合 遍历set集合
    (1)集合 ---遍历map集合
  • 原文地址:https://www.cnblogs.com/Kv-Stalin/p/9042135.html
Copyright © 2011-2022 走看看