[SCOI2007]压缩

状态:设\(dp[i][j]\)表示前i个字符,最后一个\(M\)放置在\(j\)位置之后的最短字串长度.

转移有三类,用刷表法来实现.

第一种是直接往压缩串后面填字符,这样就是:

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

另外一种就是往字串里添加\(R\),要满足相邻两个字符串是匹配的,可以用字符串哈希来快速匹,另外下面的\(k\)和\(sz\)要倍增往后跳(因为重复的串长在成倍增加,题目的样例解释的很清楚了).

\[dp[k][j]=min(dp[k][j],dp[k-sz][j]+1)
\]

当然还要往后填\(M\)

\[dp[i][i]=min(dp[i][i],dp[i][j])
\]

时间复杂度\(O(n^2logn)\)

代码很好懂.

#include<bits/stdc++.h>
#define ull unsigned long long
#define maxn 55
using namespace std;
const int base=233;
ull ha[maxn],pw[maxn];
char s[maxn];
int n,ans,dp[maxn][maxn];
ull gethash(int l,int r){return ha[r]-ha[l-1]*pw[r-l+1];}
int main()
{
scanf("%s",s+1);n=strlen(s+1);pw[0]=1;
for(int i=1;i<=n;i++)ha[i]=ha[i-1]*base+s[i];
for(int i=1;i<=n;i++)pw[i]=pw[i-1]*base;
memset(dp,0x3f,sizeof(dp));dp[1][0]=1;
//dp[i][j]表示前i个字符,上一个M放在j位置之后的最短加密字串
for(int i=1;i<=n;i++)
{
for(int j=0;j<i;j++)dp[i][i]=min(dp[i][i],dp[i][j]+1);
for(int j=0;j<=i;j++)
{
dp[i+1][j]=min(dp[i+1][j],dp[i][j]+1);//往后直接添加字母
if(i==j)continue;
int sz=i-j;ull haha=gethash(j+1,i);
for(int k=i+sz;k<=n;k+=sz)//倍增加R
{
if(haha==gethash(k-sz+1,k))//哈希匹配字符串
dp[k][j]=min(dp[k][j],dp[k-sz][j]+1);
else break;
haha=haha*pw[sz]+haha;sz<<=1;
}
}
}
ans=1e9;
for(int j=0;j<n;j++)ans=min(ans,dp[n][j]);
cout<<ans<<endl;
return 0;
}

[SCOI2007]压缩(动态规划,区间dp,字符串哈希)的更多相关文章

  1. [SCOI2007]压缩(区间dp)

    神仙题,看了半天题解才看明白... 因为题目里说如果没有m,会自动默认m在最前面. 我们设计状态为dp[l][r][0/1]为在区间l到r中有没有m的最小长度. 转移:枚举我们要压缩的起点,dp[l] ...

  2. bzoj 1068: [SCOI2007]压缩【区间dp】

    神区间dp 设f[l][r][0]为在l到r中压缩的第一个字符为M,并且区间内只有这一个M,f[l][r][0]为在l到r中压缩的第一个字符为M,并且区间内有两个及以上的M 然后显然的转移是f[i][ ...

  3. 1068. [SCOI2007]压缩【区间DP】

    Description 给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息.压缩后的字符串除了小 写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上 ...

  4. BZOJ1068 [SCOI2007]压缩 【区间dp】

    题目 给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息.压缩后的字符串除了小 写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上一个M(如果当前位 ...

  5. 2018.10.20 bzoj1068: [SCOI2007]压缩(区间dp)

    传送门 这题转移很妙啊. f[l][r][1/0]f[l][r][1/0]f[l][r][1/0]表示对于区间[l,r][l,r][l,r]有/无重复的机会时压缩的最小值. 那么可以从三种情况转移过来 ...

  6. 动态规划——区间dp

    在利用动态规划解决的一些实际问题当中,一类是基于区间上进行的,总的来说,这种区间dp是属于线性dp的一种.但是我们为了更好的分类,这里仍将其单独拿出进行分析讨论. 让我们结合一个题目开始对区间dp的探 ...

  7. 动态规划——区间DP,计数类DP,数位统计DP

    本博客部分内容参考:<算法竞赛进阶指南> 一.区间DP 划重点: 以前所学过的线性DP一般从初始状态开始,沿着阶段的扩张向某个方向递推,直至计算出目标状态. 区间DP也属于线性DP的一种, ...

  8. 模板 - 动态规划 - 区间dp

    因为昨天在Codeforces上设计的区间dp错了(错过了上紫的机会),觉得很难受.看看学长好像也有学,就不用看别的神犇的了. 区间dp处理环的时候可以把序列延长一倍. 下面是 $O(n^3)$ 的朴 ...

  9. 动态规划---区间dp

    今天写内网题,连着写了两道区间dp,这里就总结一下. 区间dp思想主要是先枚举f[i][j]中的i,再枚举j,再枚举一个1~j之间的变量k,一般是f[i][j] = max(f[i][j],f[i][ ...

随机推荐

  1. 缓存实践Cache Aside Pattern

    Cache Aside Pattern旁路缓存,是对缓存应用的一个总结,包括读数据方案和写数据方案. 读数据方案 先读cache,如果命中则返回 如果miss则读db 将db的数据存入缓存 写数据方案 ...

  2. 【弱化版】【P3371 【模板】单源最短路径(弱化版)】-C++

    →原题传送门← 看到题目描述我就知道,这道题不能用SPFA[手动补滑稽] 那么我这道题目采用的是dijkstra算法不了解的去补一下知识哈. dij的模板: #include<bits/stdc ...

  3. [ERROR]:INST-07008: Oracle 主目录(O) 位置的验证失败。用户没有创建主目录/实例位置的权限

    安装weblogic12.1.3.0时,输入的安装命令是: 老是报这个错误. 百度半天好像没人报过这错……看来只有我这么粗心了…… 后来发现wls.rsp里面的Oracle_HOME指向目录错误,修改 ...

  4. vs2010 安装项目完成桌面快捷方式无法定位程序文件夹 解决方法

    本文转载自http://www.cnblogs.com/jasonxuvip/archive/2012/07/13/2589952.html 软件打包工具有很多种,让人不知道选那个方便自己使用,Tig ...

  5. 一文带你了解git

    git简介 什么是git? git是当今世界上最先进的分布式的版本控制系统. 版本控制系统分集中式的和分布式的,集中式的主要代表有CVS.SVN,而Git是分布式版本控制系统的佼佼者. 那什么是集中式 ...

  6. mysqli_query 的定义和用法

     定义和用法 mysqli_query() 函数执行某个针对数据库的查询. 语法 mysqli_query(connection,query,resultmode); 参数 描述 connecti ...

  7. Java--重载与重写的区别

    1.重写必须继承,重载不用.2.重写的方法名,参数数目相同,参数类型兼容,重载的方法名相同,参数列表不同.3.重写的方法修饰符大于等于父类的方法,重载和修饰符无关.4.重写不可以抛出父类没有抛出的一般 ...

  8. Codeforces Round #486 (Div. 3) C "Equal Sums" (map+pair<>)

    传送门 •题意 给k个数列,从中k个数列中找出任意2个数列 i ,j 使得数列i删除第x个数,和数列j删除第y个数的和相等 若存在,输出 i ,x 和 j,y •思路 每个数列之间的联系为数列的和之间 ...

  9. spark 源码分析之八--Spark RPC剖析之TransportContext和TransportClientFactory剖析

    spark 源码分析之八--Spark RPC剖析之TransportContext和TransportClientFactory剖析 TransportContext 首先官方文档对Transpor ...

  10. [填坑] ubuntu检测不到外接显示器

    笔记本是win10+ubuntu18双系统,今天ubuntu(开启nivida独显状态)突然无法连外接屏幕,但切换win10就可以显示. 贴吧找到的简单解决方法,不需要重装驱动,记录分享在这里: su ...