题目传送门

字符串折叠

题目描述

折叠的定义如下:

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


  分析:

  K_lord的考试里面出的题目。考的时候直接弃疗。。。(先膜一波老余AK%%%)

  需要用区间DP来做,首先定义动规数组f[l][r],表示从l到r这一段区间内的字符串折叠后能得到的最短结果。那么枚举折叠的区间,然后枚举左右区间,再枚举可折叠的长度,也就是枚举区间长度的所有因数,然后进行判断该区间是否可以折叠,如果可以则进行状态转移。值得注意的是,转移完以后还需要在进行依次断点枚举,表示将该区间分成两次折叠,看能否得到最短折叠。当然,蒟蒻不擅长动规,还是听了老余讲课,又参考了大佬的博客才弄懂的。如果上面的思路不太懂,就直接看代码吧,代码好懂多了。

  Code:

#include<bits/stdc++.h>
using namespace std;
char s[];int f[][];
inline bool check(int l,int r,int k)
{
for(int i=l+k,p=;i<=r;i++,p=(p+)%k)
if(s[i]!=s[l+p])return false;
return true;
}
inline int get(int x)
{int ret=;while(x)x/=,ret++;return ret;}
int main()
{
memset(f,0x7f,sizeof(f));
scanf("%s",s+);int n=strlen(s+);
for(int i=;i<=n;i++)f[i][i]=;
for(int i=;i<=n;i++)
for(int l=;l+i-<=n;l++){
int r=l+i-;
for(int k=;k*k<=i;k++){
if(i%k==){
if(check(l,r,i/k))f[l][r]=min(f[l][r],f[l][l+i/k-]+get(k));
if(check(l,r,k))f[l][r]=min(f[l][r],f[l][l+k-]+get(i/k));}}
for(int k=l;k<=r;k++)
f[l][r]=min(f[l][r],f[l][k]+f[k+][r]);}
printf("%d",f[][n]);return ;
}

洛谷P4302 [SCOI]字符串折叠 [字符串,区间DP]的更多相关文章

  1. luogu4302字符串折叠题解--区间DP

    题目链接 https://www.luogu.org/problemnew/show/P4302 分析 很明显一道区间DP题,对于区间\([l,r]\)的字符串,如果它的字串是最优折叠的,那么它的最优 ...

  2. [SCOI2003]字符串折叠(区间dp)

    P4302 [SCOI2003]字符串折叠 题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS ...

  3. bzoj 1090 [SCOI2003]字符串折叠(区间DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1090 [题意] 给定一个字符串,问将字符串折叠后的最小长度. [思路] 设f[i][j ...

  4. [bzoj1090][SCOI2003]字符串折叠_区间dp

    字符串折叠 bzoj-1090 SCOI-2003 题目大意:我说不明白...链接 注释:自己看 想法:动态规划 状态:dp[i][j]表示从第i个字符到第j个字符折叠后的最短长度. 转移:dp[l] ...

  5. [luogu1090 SCOI2003] 字符串折叠(区间DP+hash)

    传送门 Solution 区间DP,枚举断点,对于一个区间,枚举折叠长度,用hash暴力判断是否能折叠即可 Code #include <cstdio> #include <cstr ...

  6. 【洛谷】P1063 能量项链【区间DP】

    P1063 能量项链 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子, ...

  7. 洛谷 P1220 关路灯 (贪心+区间dp)

    这一道题我一直在想时间该怎么算. 看题解发现有个隐藏的贪心. 路径一定是左右扩展的,左右端点最多加+1(我竟然没发现!!) 这个性质非常重要!! 因此这道题用区间dp f[i][j]表示关完i到j的路 ...

  8. 1090. [SCOI2003]字符串折叠【区间DP】

    Description 折叠的定义如下: 1. 一个字符串可以看成它自身的折叠.记作S  S 2. X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S)  SSSS…S(X个S). ...

  9. bzoj 1090: [SCOI2003]字符串折叠【区间dp】

    设f[i][j]为区间(i,j)的最短长度,然后转移的话一个是f[i][j]=min(j-i+1,f[i][k]+f[k+1][j]),还有就是把(k+1,j)合并到(i,k)上,需要判断一下字符串相 ...

随机推荐

  1. Android之极光推送发送自定义消息

    Android端实现主要代码: <span style="font-size:14px;">import java.io.IOException; import jav ...

  2. ZooKeeper配额指南(十)

    配额 ZK有命名空间和字节配额.你可以使用ZooKeeperMain类来设置配额.ZK打印警告信息如果用户超过分配给他们的配额.这些信息被打印到ZK的日志中. $java -cp zookeeper. ...

  3. ZooKeeper翻译(一)

    欢迎来到Apache ZooKeeper的世界 Apache Zookeeper是一个为了开发和维护一个开源的服务的一个尝试,这个服务使高可用的分布式协作成为可能. ZooKeeper是什么? Zoo ...

  4. CodeForces527D. Fuzzy Search

    time limit per test:3 seconds memory limit per test:256 megabytes input:standard input output:standa ...

  5. 【51NOD-0】1137 矩阵乘法

    [算法]简单数学 [题解] 对于A*B=C C中第i行第j列的数字由A中第i行和B中的j列的数字各自相乘后相加得到. 所以两个矩阵能相乘要求A的列数等于B的行数,复杂度为O(n3). #include ...

  6. LCA入门题集小结

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目: How far away ? Time Limit: 2000/1000 MS (Jav ...

  7. 表格td内容超出宽度显示... table-layout: fixed;

    td宽度用百分比固定好的时候,即使设置了 white-space:nowrap;/*文本不会换行,在同一行显示*/ overflow:hidden;超出隐藏 text-overflow:ellipsi ...

  8. js_返回上一页(兼容苹果手机)

    返回上一页功能是常见的功能. 常用的有以下三种代码: window.history.go(-1); //返回上一页 window.history.back(); //返回上一页 //如果要强行刷新的话 ...

  9. 【Python学习笔记】异常处理try-except

    Python异常处理 我们一般使用try-except语句来进行异常处理. 使用except Exception as err可以统一捕捉所有异常,而也可以分开处理单个异常. # 分开捕捉单个异常 t ...

  10. Reactor与Proactor区别

    如网络编程中accept之后等待数据到达,并且读取数据为例: Reactor: 基于同步IO 1. 线程等待读取socket数据,将socketfd添加到事件分派器中,如添加到epoll: 2. 事件 ...