Compress String

时间限制:2000 ms  |  内存限制:65535 KB
难度:3
描写叙述
One day,a beautiful girl ask LYH to help her complete a complicated task—using a new compression method similar to Run Length Encoding(RLE) compress a string.Though the task is difficult, LYH is glad to help her.
The compress rules of the new method is as follows: if a substring S is repeated k times, replace k copies of S by k(S). For example, letsgogogo is compressed into lets3(go). The length of letsgogogo is
10, and the length of lets3(go) is 9. In general, the length of k(S) is (number of digits in k ) + (length of S) + 2. For example, the length of 123(abc) is 8. It is also possible that substring S
is a compressed string. For example nowletsgogogoletsgogogoandrunrunrun could be compressed as now2(lets3(go))and3(run).
In order to make the girl happy, LYH solved the task in a short time. Can you solve it?
输入
Thera are multiple test cases.

Each test case contains a string, the length of the string is no more than 200, all the character is lower case alphabet.
输出
For each test case, print the length of the shortest compressed string.
例子输入
ababcd
letsgogogo
nowletsgogogoletsgogogoandrunrunrun
例子输出
6
9
24

题意:给出一个长度不超过200的字符串。把这个字符串依照一定规则压缩,即能够把几个连续的同样子串压缩成一个串,比如能够把letsgogogo压缩为lets3(go),压缩后的子串假设还能够继续压缩。则能够继续压缩,如能够将nowletsgogogoletsgogogoandrunrunrun压缩为now2(lets3(go))and3(run)。问经过压缩后这个字符串的最短长度是多少。

分析: 区间DP,dp[i][j]表示从i到j的字符串表示的最短长度。

dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j])。

然后去推断当前子串能不能压缩。即是否由反复字符串组成,推断时仅仅需暴力枚举反复长度,去推断就可以。

          假设当前子串能够压缩,则dp[i][j] = min(dp[i][j], dp[i][i + len - 1] + 2 + digcount((j - i + 1) / len));。

注意假设是数字,要用数字的位数表示添加的个数。而不是单纯的添加1.

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 210;
#define INF 0x3fffffff
char str[N];
int n, dp[N][N]; int digit_cnt(int x)
{
int a = 0;
while(x) {
a++;
x /= 10;
}
return a;
} bool check(int l, int r, int len)
{
if((r - l + 1) % len) return false;
for(int i = l; i < l + len; i++) {
for(int j = i + len; j <= r; j += len)
if(str[i] != str[j]) return false;
}
return true;
} int get_ans()
{
int i, j, k;
n = strlen(str+1);
for(i = 1; i <= n; i++) dp[i][i] = 1;
for(i = n - 1; i >= 1; i--) {
for(j = i + 1; j <= n; j++) {
dp[i][j] = INF;
for(k = i; k < j; k++)
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j]);
for(int len = 1; len <= j-i+1; len++) {
if(check(i, j, len)) {
dp[i][j] = min(dp[i][j], dp[i][i+len-1] + 2 + digit_cnt((j - i + 1) / len));
}
}
}
}
return dp[1][n];
} int main()
{
while(~scanf("%s", str+1)) {
printf("%d\n", get_ans());
}
return 0;
}

NYOJ 1067 Compress String(区间dp)的更多相关文章

  1. Codeforces Round #354 (Div. 2)-C. Vasya and String,区间dp问题,好几次cf都有这种题,看来的好好学学;

    C. Vasya and String time limit per test 1 second memory limit per test 256 megabytes input standard ...

  2. nyoj 460 项链 (区间dp)

    项链 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子, ...

  3. codeforces#1120C. Compress String(dp+后缀自动机)

    题目链接: https://codeforces.com/contest/1120/problem/C 题意: 从前往后压缩一段字符串 有两种操作: 1.对于单个字符,压缩它花费$a$ 2.对于末尾一 ...

  4. eduCF#61 F. Clear the String /// 区间DP 消除连续一段相同字符 全部消完的最少次数

    题目大意: 给定字符串 每次消除可消除连续的一段相同的字符的子串 求消除整个字符串的最少消除次数 #include <bits/stdc++.h> using namespace std; ...

  5. hdu2476 String painter(区间dp)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2476 Problem Description There are two strings ...

  6. nyoj 737 石子合并(一)。区间dp

    http://acm.nyist.net/JudgeOnline/problem.php?pid=737 数据很小,适合区间dp的入门 对于第[i, j]堆,无论你怎么合并,无论你先选哪两堆结合,当你 ...

  7. NYOJ 题目15 括号匹配(二)(区间DP)

    点我看题目 题意 : 中文题不详述. 思路 : 本来以为只是个小模拟,没想到是个区间DP,还是对DP不了解. DP[i][j]代表着从字符串 i 位置到 j 位置需要的最小括号匹配. 所以初始化的DP ...

  8. [CF1107E]Vasya and Binary String【区间DP】

    题目描述 Vasya has a string s of length n consisting only of digits 0 and 1. Also he has an array a of l ...

  9. HDU2476 String painter——区间DP

    题意:要把a串变成b串,每操作一次,可以使a串的[l,r]区间变为相同的一个字符.问把a变成b最少操作几次. 这题写法明显是区间dp ,关键是处理的方法. dp[l][r]表示b串的l~r区段至少需要 ...

随机推荐

  1. Knockout v3.4.0 中文版教程-9-计算监控-API参考

    5.参考 下面的内容描述了如何构建和使用计算监控. 1. 构建一个计算监控 可以用如下的形式构建一个计算监控: ko.computed( evaluator [, targetObject, opti ...

  2. Python基础之(判断,循环,列表,字典)

    一.python介绍 Python是一种简单易学,功能强大的编程语言,它有高效率的高层数据结构,简单而有效地实现面向对象编程.Python简洁的语法和对动态输入的支持,再加上解释性语言的本质,使得它在 ...

  3. Configure Always On Availability Group for SQL Server on Ubuntu

    下面简单介绍一下如何在Ubuntu上一步一步创建一个SQL Server AG(Always On Availability Group),以及配置过程中遇到的坑的填充方法. 目前在Linux上可以搭 ...

  4. 利用pytorch复现spatial pyramid pooling层

    sppnet不讲了,懒得写...直接上代码 from math import floor, ceil import torch import torch.nn as nn import torch.n ...

  5. 九度oj 题目1179:阶乘

    题目描述: 输入n, 求y1=1!+3!+...m!(m是小于等于n的最大奇数)y2=2!+4!+...p!(p是小于等于n的最大偶数). 输入: 每组输入包括1个整数:n 输出: 可能有多组测试数据 ...

  6. 九度oj 题目1088:剩下的树

    题目描述: 有一个长度为整数L(1<=L<=10000)的马路,可以想象成数轴上长度为L的一个线段,起点是坐标原点,在每个整数坐标点有一棵树,即在0,1,2,...,L共L+1个位置上有L ...

  7. xmpp 与服务器连接并身份验证成功

    *  XMPP的特点,所有的请求都是通过代理的方式实现的 * *  因为xmpp是经由网络服务器进行数据通讯的,因此所有的,因此所有的请求都是提交给服务器处理 * *  服务器处理完毕止呕,以代理的方 ...

  8. 算法复习——迭代加深搜索(骑士精神bzoj1085)

    题目: Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相 ...

  9. [ZJOI2005]午餐 (贪心,动态规划)

    题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的口味(以及胃口)不同,所以他们要吃的菜各 ...

  10. #ifdef endif 用法

    "#ifdef 语句1 程序2 #endif“ 可翻译为:如果宏定义了语句1则程序2. 作用:我们可以用它区隔一些与特定头文件.程序库和其他文件版本有关的代码. 代码举例:新建define. ...