Codeforces Round #543 (Div. 2) F dp + 二分 + 字符串哈希
https://codeforces.com/contest/1121/problem/F
题意
给你一个有n(<=5000)个字符的串,有两种压缩字符的方法:
1. 压缩单一字符,代价为a
2. 压缩一个串,条件是这个串是前面整个串的连续子串,代价为b
题解
- n<=5000
- 定义dp[i]为压缩前i个字符的代价,则答案为dp[n]
- dp[i]=min(dp[i-1]+a,min(dp[j]+b)(即[j+1,i]为[1,j]的子串))
- 用字符串哈希处理判定一个串是否为前面的子串
坑点
- 串abab,如何判定后面一个ab是前面ab的子串?
- 照旧给每一个位置加权
- 判定的时候,首先将权值加到同一个权级再比较
比如存在一个首字符在i和一个首字符在j的串,那么比较的时候哈希值分别都要乘以(size-i)和(size-j),得到权级都是size的串
- 两层for已经是n*n复杂度,还需要判定后面的串是否是前面串的子串?
- 一开始想法就是用一个map[i]记录每个位置之前哈希值的出现次数,但是会超内存
- 换一个\(n*n*log(n)\)的算法,二分找出最小的位置\(log(n)\),枚举前面每一个位置固定长度串\(n\)
代码
#include<bits/stdc++.h>
#define P 47 //加权的质数较小
#define mod 1000000003 //哈希表的质数较大
#define ll long long
using namespace std;
int n,a,b,i,j,sum[5005],dp[5005],pw[6000],l,mid,r;
char s[5005];
void init(){
pw[0]=1;
for(int i=1;i<=n+100;i++)
pw[i]=(ll)pw[i-1]*P%mod;
for(int i=1;i<=n;i++)
sum[i]=(sum[i-1]+(ll)pw[i]*(s[i]-'a'+1)%mod)%mod;
}
int geths(int i,int j){
return (int)(((ll)sum[j]-sum[i-1]+mod)%mod*pw[n+50-i]%mod);
}
int ck(int p,int i,int j,int len){
int hs=geths(i,j);
for(int k=1;k<=p-len+1;k++){
if(geths(k,k+len-1)==hs)return 1;
}
return 0;
}
int main(){
cin>>n>>a>>b;
scanf("%s",s+1);
init();
dp[0]=0;
for(i=1;i<=n;i++){
dp[i]=dp[i-1]+a;
l=1;r=i-1;
while(l<r){
mid=(l+r)/2;
if(ck(i-mid,i-mid+1,i,mid))l=mid+1;
else r=mid;
}
while(!ck(i-l,i-l+1,i,l))l--;
if(l>=1)dp[i]=min(dp[i-l]+b,dp[i]);
}
cout<<dp[n];
}
Codeforces Round #543 (Div. 2) F dp + 二分 + 字符串哈希的更多相关文章
- Codeforces Round #486 (Div. 3) F. Rain and Umbrellas
Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...
- Codeforces Round #501 (Div. 3) F. Bracket Substring
题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...
- Codeforces Round #499 (Div. 1) F. Tree
Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...
- Codeforces Round #485 (Div. 2) F. AND Graph
Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...
- Codeforces Round #479 (Div. 3) F. Consecutive Subsequence (简单dp)
题目:https://codeforces.com/problemset/problem/977/F 题意:一个序列,求最长单调递增子序列,但是有一个要求是中间差值都是1 思路:dp,O(n)复杂度, ...
- Codeforces Round #552 (Div. 3) F. Shovels Shop (前缀和预处理+贪心+dp)
题目:http://codeforces.com/contest/1154/problem/F 题意:给你n个商品,然后还有m个特价活动,你买满x件就把你当前的x件中最便宜的y件价格免费,问你买k件花 ...
- Codeforces Round #527 (Div. 3) F. Tree with Maximum Cost 【DFS换根 || 树形dp】
传送门:http://codeforces.com/contest/1092/problem/F F. Tree with Maximum Cost time limit per test 2 sec ...
- Codeforces Round #531 (Div. 3) F. Elongated Matrix(状压DP)
F. Elongated Matrix 题目链接:https://codeforces.com/contest/1102/problem/F 题意: 给出一个n*m的矩阵,现在可以随意交换任意的两行, ...
- Codeforces Round #530 (Div. 2) F 线段树 + 树形dp(自下往上)
https://codeforces.com/contest/1099/problem/F 题意 一颗n个节点的树上,每个点都有\(x[i]\)个饼干,然后在i节点上吃一个饼干的时间是\(t[i]\) ...
随机推荐
- openal支持的通道数和声道数
alext.h: #define AL_FORMAT_QUAD8 0x1204 101 #define AL_FORMAT_QUAD16 0x1205 102 #define AL_FORMAT_Q ...
- Qt: 记事本源代码
界面编程之实例学习,系统记事本是个极好的参考,初学Delphi及后之c#,皆以记事本为参考,今以Qt学习,亦是如此. 期间搭建开发环境,复习c++知识,寻找模块对应功能,不一而足:现刻录其模块代码,以 ...
- swift - UIWebView 和 WKWebView(iOS12 之后替换UIWebView)
1.iOS12 之前 使用 UIWebView 1> private lazy var webV : UIWebView = { let v = UIWebView(frame: self.vi ...
- java 线程Thread 技术--1.5 Executor Executors,ThreadPool,Queue
Executors : Executors ,就是一个线程工具类:大部分操作线程的方法,都可以在这个工具类中就行创建,执行,调用一些线程的方法: Executor : 用于执行和提交一个runnabl ...
- build.js
// https://github.com/shelljs/shelljs// 检查NodeJS和npm的版本require('./check-versions')() process.env.NOD ...
- bootstrap 折叠collapse失效
手动点击折叠,然后调用折叠全部以后,在手动点击折叠项,折叠失效. 方法,折叠项是通过添加或删除".in"来实现,实现如下 $(".collapse.in").c ...
- C++中string类
https://blog.csdn.net/sinat_36184075/article/details/54836053 https://blog.csdn.net/fdqw_sph/article ...
- Oracle Linux下数据库操作的相关问题
1.su - oracle 切换到oracle用户 lsnrctl status 查看数据库监听状态 lsnrctl start 打开数据库监听 2.Connected to an idle inst ...
- 用vs2015 编译 web app ionic
1.要下载https://git-for-windows.github.io/ 2.下载ionic模版
- 6.26实力测试(小错笑cry)
6.26测试 本次考试的粗心不忍吐槽(自带贴吧喷水表情),本次考试主要考察的知识点如下: 算法的分析与精简 暴力枚举输出字符 判断与枚举的综合考察 题目 第一题 [问题描述] 在一口井里,有一只神牛( ...