UVA1351-----String Compression-----区间DP(记忆化搜索实现)
本文出自:http://blog.csdn.net/dr5459
题目地址:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4097
题目意思:
以下内容出自http://blog.csdn.net/shuangde800/article/details/9885147
我是按照他的想法,算法是自己实现的
给一个字符串,可以把连续相同的部分进行缩写成k(S)的形式,S是一个字符串,k表示有连续相同的S
例如,abgogogogo,可以缩写成ab4(go). 还可以嵌套缩写,比如
“nowletsgogogoletsgogogo”, 缩写成“now2(lets3(go))”
思路:
一道区间dp,但是这题并不好想
f(i, j)表示字符串的i~j位的最小位数
那么
f(i, j) = min{
min{ f(i,k)+f(k+1, j), i<=k<j },
min{ digitNum(k)+f[l][l+k-1]+2, 如果字符串可以由前k个字符串重复组成的 }
}
digitNum(k)表示数字k的位数
判断区间(i, j)是否有由连续k个组成的字符串连续组成的,直接用O(n)的时间判断
区间DP用记忆画搜索比较容易实现,不用仔细去想迭代的写法
所以以后写区间DP就可以用记忆化搜索的写法
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string.h> using namespace std; const int maxn = 300;
int dp[maxn][maxn];
char s[maxn];
const int INF = 0x3f3f3f3f; bool check(int l,int r,int k)
{
int i;
int len = r-l+1;
i=0;
while(i<k)
{
int p;
for(p=1;l+p*k+i<=r;p++)
{
if(s[l+i] != s[l+p*k+i])
return false;
}
i++;
} return true;
} int min(int a,int b)
{
return a<b?a:b;
} int digitnum(int k)
{
int len = 0;
while(k>0)
{
len++;
k/=10;
}
return len;
} int DP(int l,int r)
{
if(dp[l][r] != -1)
return dp[l][r]; int len = r-l+1;
int d; dp[l][r] = INF; for(int k=l;k<r;k++)
dp[l][r] = min(dp[l][r],DP(l,k)+DP(k+1,r)); for(d=1;d<=len/2;d++)
{
if(len%d != 0)
continue;
if(check(l,r,d))
{
dp[l][r] = min(dp[l][r],digitnum(len/d)+DP(l,l+d-1)+2);
}
} return dp[l][r];
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
memset(dp,-1,sizeof(dp));
int len = strlen(s);
int i;
for(i=0;i<len;i++)
dp[i][i] = 1;
cout<<DP(0,len-1)<<endl;
}
return 0;
}
UVA1351-----String Compression-----区间DP(记忆化搜索实现)的更多相关文章
- (区间dp + 记忆化搜索)Treats for the Cows (POJ 3186)
http://poj.org/problem?id=3186 Description FJ has purchased N (1 <= N <= 2000) yummy treats ...
- UVA 10003 Cutting Sticks 区间DP+记忆化搜索
UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的 ...
- uva 10891 区间dp+记忆化搜索
https://vjudge.net/problem/UVA-10891 给定一个序列x,A和B依次取数,规则是每次只能从头或者尾部取走若干个数,A和B采取的策略使得自己取出的数尽量和最大,A是先手, ...
- loj 1031(区间dp+记忆化搜索)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1031 思路:dp[i][j]表示从区间i-j中能取得的最大值,然后就是枚举分割点了. ...
- Ural 1183 Brackets Sequence(区间DP+记忆化搜索)
题目地址:Ural 1183 最终把这题给A了.. .拖拉了好长时间,.. 自己想还是想不出来,正好紫书上有这题. d[i][j]为输入序列从下标i到下标j最少须要加多少括号才干成为合法序列.0< ...
- BZOJ1055[HAOI2008]玩具取名 【区间dp + 记忆化搜索】
题目 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后 他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够 ...
- HDU 2517 / POJ 1191 棋盘分割 区间DP / 记忆化搜索
题目链接: 黑书 P116 HDU 2157 棋盘分割 POJ 1191 棋盘分割 分析: 枚举所有可能的切割方法. 但如果用递归的方法要加上记忆搜索, 不能会超时... 代码: #include& ...
- hdu 4597 Play Game(区间dp,记忆化搜索)
Problem Description Alice and Bob are playing a game. There are two piles of cards. There are N card ...
- poj 1088 滑雪(区间dp+记忆化搜索)
题目链接:http://poj.org/problem?id=1088 思路分析: 1>状态定义:状态dp[i][j]表示在位置map[i][j]可以滑雪的最长区域长度: 2>状态转移方程 ...
- 洛谷1880 区间dp+记忆化搜索 合并石子
题目网址:https://www.luogu.com.cn/problem/P1880 题意是:给定一个序列,最小规则是相邻两个值的合并,开销是他们的和,将整个序列合并成一个值的情况下,求解该值的最小 ...
随机推荐
- mongodb中数据类型的坑
在mongodb中,我们给每个文档插入数据的时候,mongodb自动会为我们插入的数据创建数据类型.由于mongodb是一个非结构化的数据存储系统,因此在文档中你可以随意插入不同类型的字段,这和MyS ...
- python排序(冒泡, 快速)
之前用java时学习的一些基础算法,今天在python上也研究下. 1. 冒泡排序 算法步骤: 50 30 70 90 10 1)50 跟 30 比不用交换. 2)步数+1, 30 跟70比 ...
- MySQLdb-python的安装
第一步下载: 第一步:进入https://github.com/farcepest/MySQLdb1/ 第二步:解压 Shell>unzip /root/MySQLdb1-MySQLdb-1.3 ...
- 正确决解Hibernate4.*中:Connection cannot be null when 'hibernate.dialect' not set
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hi ...
- Oracle EBS-SQL (WIP-4):检查检查成品标准作业是否勾选"固定"标识.sql
select WE.DESCRIPTION 任务说明, ...
- QueryString和BASE64
加号(+)是BASE64编码的一部分,而加号在QueryString中被当成是空格.因此,当一个含有BASE64编码的字符串直接作为URL的一部分时,如果其中含有加号,则使用QueryString读取 ...
- Qt 中程序自动重启
参照至 dbzhang老师的博文,记录于此....... 要想理解重启,先得看看Qt程序怎么退出! 1.退出 int main(int argc, char** argv) { QApplicatio ...
- yii post delete request more safe
常规的delete方法如下: /** * Deletes a particular model. * If deletion is successful, the browser will be r ...
- rpm安装软件(需管理员权限)
常用命名规范 linux-1.2.0-30.e16.i686.rpm rpm基本命令 安装rpm -i software.rpm 卸载rpm -e software 升级rpm -U software ...
- 利用boost做string到wstring转换,以及字符集转换 - Error - C++博客
利用boost做string到wstring转换,以及字符集转换 - Error - C++博客 利用boost做string到wstring转换,以及字符集转换 #include <boost ...