博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[SCOI2003]字符串折叠 (区间DP)
阅读量:5087 次
发布时间:2019-06-13

本文共 1217 字,大约阅读时间需要 4 分钟。

题目描述

折叠的定义如下:

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

 

转载于:https://www.cnblogs.com/Kv-Stalin/p/9042135.html

你可能感兴趣的文章
window.event在IE和Firefox的异同
查看>>
常见的js算法面试题收集,es6实现
查看>>
IO流写出到本地 D盘demoIO.txt 文本中
查看>>
Windows10 下Apache服务器搭建
查看>>
HDU 5458 Stability
查看>>
左手坐标系和右手坐标系
查看>>
solr后台操作Documents之增删改查
查看>>
http://yusi123.com/
查看>>
文件文本的操作
查看>>
Ubuntu linux下gcc版本切换
查看>>
记一次Web服务的性能调优
查看>>
jQuery.form.js使用
查看>>
(转)linux sort,uniq,cut,wc命令详解
查看>>
关于ExecuteNonQuery执行的返回值(SQL语句、存储过程)
查看>>
UVa540 Team Queue(队列queue)
查看>>
mysql数据增删改查
查看>>
akka之种子节点
查看>>
不知道做什么时
查看>>
matlab 给某一列乘上一个系数
查看>>
密码学笔记——培根密码
查看>>