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

题解

令$f_{i,j}$为[i,j)这一段字符串的最短折叠长度。

那么,显而易见的有

$$f_{i,i+1}=1$$

$$f_{i,j}=min\left(min\{f_{i,k} +f_{k,j}\mid i < k < j\}, min\{f_{i,k} + 2 + num((j - i) / (k - i)) \mid i < k < j, S_{i,j} = \frac{j-i}{k-i}S_{i,k}\}\right)$$

其中$num(x)$表示$x$的十进制位数, $S_{i,j}$表示字符串中i到j的一部分。

那么,应该如何判断$S_{i,j}$是否由$S_{i,k}$重复得到呢?

比较$S_{i,j-k}$和$S_{i+k,j}$即可。

暴力比较就好了。

时间复杂度$O(n^3logn)$

咦,为什么是这个复杂度(不想看请跳过)?

对于每一个长度$len$,都有$n-len+1$个长为$len$的区间,每个区间所需要的字符比较次数至多为

$$\sum_{d|len}(len-d)$$

那么总比较次数至多为

$$\begin{aligned}
\sum_{l=1}^n(n-l+1)\sum_{d|l}(l-d) &\leq \sum_{l=1}^nn\sum_{d|l}l\\
&= n\sum_{l=1}^nl\sum_{d|l}1\\
&= n\sum_{d=1}^n\sum_{d|l, 1 \leq l \leq n}l\\
&= n\sum_{d=1}^nd\sum_{l'=1}^{\lfloor\frac{n}d\rfloor}l'\\
&= n\sum_{d=1}^nd\frac{\lfloor\frac{n}d\rfloor\left(\lfloor\frac{n}d\rfloor+1\right)}2\\
&\leq n\sum_{d=1}^n\frac{n\left(\frac{n}d+1\right)}2\\
&\backsim \frac{n^3}2\sum_{d=1}^n\frac{1}d\\
&=O(n^3logn)\end{aligned}$$

所以暴力比较只多了一个$log$,可以接受。

附代码:

#include <algorithm>
#include <cstdio>
#include <cstring>
using std::min;
char s[105];
inline bool eq(int b1, int b2, int len) {
return !strncmp(s + b1, s + b2, len);
}
inline int wei(int x) {
int t = 1;
while (x /= 10) ++t;
return t;
}
int f[105][105];
int main() {
scanf("%s", s);
int n = strlen(s);
for (int len = 1; len <= n; ++len)
for (int i = 0; i + len <= n; ++i) {
int j = i + len;
f[i][j] = len;
for (int k = i + 1; k < j; ++k) {
f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
if (!(len % (k - i)) && eq(i, k, j - k))
f[i][j] = min(f[i][j], f[i][k] + 2 + wei(len / (k - i)));
}
}
printf("%d\n", f[0][n]);
return 0;
}

  

BZOJ1093 [SCOI2003]字符串折叠的更多相关文章

  1. BZOJ1090: [SCOI2003]字符串折叠

    区间dp. 一种是分段dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); 一种是这一段可以缩写dp[i][j]=min(dp[i][j],dp[i][l]+2+ca ...

  2. BZOJ 1090: [SCOI2003]字符串折叠 区间DP

    1090: [SCOI2003]字符串折叠 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  3. 【BZOJ1090】[SCOI2003]字符串折叠(动态规划)

    [BZOJ1090][SCOI2003]字符串折叠(动态规划) 题面 BZOJ 洛谷 题解 区间\(dp\).设\(f[i][j]\)表示压缩\([i,j]\)区间的最小长度.显然可以枚举端点转移.再 ...

  4. 【bzoj1090】 [SCOI2003]字符串折叠

    [bzoj1090] [SCOI2003]字符串折叠 2014年3月9日3,1140 Description 折叠的定义如下: 1. 一个字符串可以看成它自身的折叠.记作S  S 2. X(S)是X ...

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

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

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

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

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

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

  8. 【BZOJ】1090: [SCOI2003]字符串折叠(dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1090 随便yy一下.. 设f[i,j]表示i-j的最小长度 f[i, j]=min{j-i+1, f ...

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

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

随机推荐

  1. iOS ---进阶之摇一摇

    1.摇一摇的原理分析 1)在摇动手机时会产生一个动画,界面的图片会在中间分开分别进行向上.向下的位置移动. 分析:此过程就是在主屏幕上设置两个imageView,在开始摇动的方法中对这两个imageV ...

  2. 「PKUWC2018」Slay the Spire

    题目链接 题意分析 这个题其实不是期望 就是一共有\(C_{2n}^m\)种情况 每一种情况选择\(k\)张牌 然后求最大攻击值的总和 我们考虑 当前抽出了选出了\(i\)张强化牌 \(m-i\)张攻 ...

  3. AFNetworking 3.1.0 使用中某些知识点讲解

    # POST / GET  请求 /*! 首先要知道,POST请求不能被缓存,只有 GET 请求能被缓存.因为从数学的角度来讲,GET 的结果是 幂等 的,就好像字典里的 key 与 value 就是 ...

  4. 在Eclipse之中调试FastDFS-storage

    FDFS版本为5.03 1.首先在eclipse之中创建一个C/C++工程,取名为FastDFS_v5.03 2.将FastDFS源码解压后拷贝到新创建的工程目录下,然后在ecipse之中刷新下工程就 ...

  5. Python unittest第二篇:测试夹具

    关于测试夹具,我们知道,以类为对象的话,在python里对应的方法分别是test_isupper.test_upper, 那么以测试case为单位呢? 这时候,就要提到我们的setup()和tearD ...

  6. [Alpha]Scrum Meeting#5

    github 本次会议项目由PM召开,时间为4月7日晚上10点30分 时长10分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写博客目录 整理清明开会记录 SiMrua 模型再训练(issue#1 ...

  7. python全栈开发_day13_迭代器和生成器

    一:迭代器 1)可迭代对象 具有内置函数__iter__的数据就是可迭代对象 2)迭代器对象 具有内置函数__next__的数据就是迭代器对象 迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象 ...

  8. 搜索引擎原理和SEO

    搜索引擎原理 通常是指收集了万维网上几千万到十几亿网页病对网页的每个词(即关键词)进行索引,建立搜索引擎数据库的全文搜索引擎. 当用户每次查询某个关键词的时候,所有在页面内容包含了该关键词的网页都作为 ...

  9. 修改hosts文件的脚本1.0

    import sys IP_input = input("Please input IP:")DNS_input = input("Please input Domain ...

  10. (转)Oracle与DB2在数据库高可用技术上的相同与差异探讨

    原文:http://www.talkwithtrend.com/Article/178339 数据库建设过程中,高可用是每一个企业数据中心数据库建设过程中至关重要的一个关注点,直接关系到业务连续性和稳 ...