HDU - 6583 Typewriter (后缀自动机+dp)
题意:你要打印一段字符串,往尾部添加一个字符需要花费p元,复制一段字符到尾部需要花费q元,求打印完全部字符的最小花费。
一开始想的贪心,后来发现忘了考虑p<q的情况了,还纳闷怎么不对..(囧)
设$dp[i]$为打印完前i个字符的最小花费
第一种转移是$dp[i+1]=min(dp[i+1],dp[i]+p)$,可以直接转移
第二种转移是$dp[j]=min(dp[j],dp[i]+q)$,对于每个i需要找到最大的j,使得$s[i+1,j]$是$s[1,i]$的子串。说到子串,就自然能想到后缀自动机。我们可以在i右移的同时扩展当前的后缀自动机,然后让j也右移,直到不能转移为止。如果对于每个i都让j从i开始往后走的话复杂度是$O(n^2)$的,会T掉,因此需要改进一下。有一个很巧妙的做法,用尺取的方法,每当i右移的时候,不必让j再从i开始走一遍,而是直接右移,如果不能转移的话,就尝试往父结点走,直到有转移为止,注意mxl(结点子串最大长度)不得小于j-i,否则无法完全覆盖$s[i+1,j]$区间。这样复杂度就是$O(n)$了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+,M=;
char s[N];
int n,fa[N],go[N][M],mxl[N],last,tot,p,q;
ll dp[N];
int newnode(int l) {int u=++tot; mxl[u]=l,memset(go[u],,sizeof go[u]); return u;}
void add(int ch) {
int p=last,np=last=newnode(mxl[p]+);
for(; p&&!go[p][ch]; p=fa[p])go[p][ch]=np;
if(!p)fa[np]=;
else {
int q=go[p][ch];
if(mxl[q]==mxl[p]+)fa[np]=q;
else {
int nq=newnode(mxl[p]+);
memcpy(go[nq],go[q],sizeof go[q]);
fa[nq]=fa[q],fa[q]=fa[np]=nq;
for(; p&&go[p][ch]==q; p=fa[p])go[p][ch]=nq;
}
}
}
int main() {
while(scanf("%s%d%d",s,&p,&q)==) {
n=strlen(s),tot=;
last=newnode();
memset(dp,0x3f,sizeof dp),dp[]=;
for(int i=,j=,u=; i<n; add(s[i]-'a'),++i) {
for(; j<n; u=go[u][s[j]-'a'],++j) {
for(; !go[u][s[j]-'a']&&fa[u]&&mxl[fa[u]]>=j-i; u=fa[u]);
if(!go[u][s[j]-'a'])break;
}
dp[i+]=min(dp[i+],dp[i]+p),dp[j]=min(dp[j],dp[i]+q);
}
printf("%lld\n",dp[n]);
}
return ;
}
后记:我又尝试了使用后缀数组+线段树的方法,复杂度$O(nlogn)$,然而这题时限卡得太死了过不去,QAQ
HDU - 6583 Typewriter (后缀自动机+dp)的更多相关文章
- HDU 6583 Typewriter(后缀自动机)
Typewrite \[ Time Limit: 1500 ms\quad Memory Limit: 262144 kB \] 题意 给出一个字符串 \(s\),现在你需要构造出这个字符串,你每次可 ...
- 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp
题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...
- HDU 5343 MZL's Circle Zhou 后缀自动机+DP
MZL's Circle Zhou Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU 6583 Typewriter 题解
——本题来自杭电多校第一场 题意:给定一个字符串,主角需要用打字机将字符串打出来,每次可以: 1.花费p来打出任意一个字符 2.花费q来将已经打出的某一段(子串)复制到后面去 对于这种最优化的问题,我 ...
- bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP
2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 583 Solved: 330[Submit][Statu ...
- fjwc2019 D1T2 原样输出(后缀自动机+dp)
#179. 「2019冬令营提高组」原样输出 暴力对每个串建后缀自动机,然后暴力枚举每个自动机的子串.可以拿到部分分. 然鹅我们可以把每个后缀自动机连起来. 我们知道,后缀自动机是用最少的点(空间)表 ...
- 【BZOJ3238】差异【后缀自动机+dp】
题意 分析 这个题目还是很优秀的.sigma(len(Ti)+len(Tj))的值是一定的=n*(n+1)*(n-1)/2.那么关键就是求任意两个后缀的lcp的和了. 我们怎么求两个后缀的lcp?如果 ...
- 【SPOJ - SUBLEX】Lexicographical Substring Search 【后缀自动机+dp】
题意 给出一个字符串和q个询问,每个询问给出一个整数k,输出第k大得子串. 分析 建后缀自动机,利用匹配边来解决.设d[v]为从状态v开始有多少不同的路径.这个显然是可以递推出来的.然后对于每个询问, ...
- 【SPOJ -NSUBSTR】Substrings 【后缀自动机+dp】
题意 给出一个字符串,要你找出所有长度的子串分别的最多出现次数. 分析 我们建出后缀自动机,然后预处理出每个状态的cnt,cnt[u]指的是u这个状态的right集合大小.我们设f[len]为长度为l ...
随机推荐
- DirectX* 11 多线程渲染的性能、方法和实践
对于在 CPU 上运行的 PC 游戏,渲染通常是主要的性能瓶颈:多线程渲染是一种消除瓶颈的有效方法.本文研究了 DirectX* 11 多线程渲染的性能可扩展性,讨论了多线程渲染的两种基本方法,并介绍 ...
- postman Tests断言
摘要:关于postman的断言方法很多,在网上随便搜寻下,能搜出一大推,什么牛鬼蛇神都有,让人眼花缭乱..甚至在应用时出现错误.Test断言都是根据js规则来写的,对于我这种不懂js语言的来说确实不友 ...
- c语言GCC mingw 64位安装
1.安装步骤和下载地址 一.MinGW简介 MinGW是是将GCC编译器和GNU Binutils移植到Win32平台下的产物,包括一系列头文件(Win32API).库和可执行文件.MinGW是从Cy ...
- 【Linux开发】linux设备驱动归纳总结(七):2.内核定时器
linux设备驱动归纳总结(七):2.内核定时器 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...
- Emgu 学习(3) 绘图,使用鼠标绘图,使用trackbar
绘图 class Program { static void Main(String[] args) { Mat img = , , DepthType.Cv8U, ); img.SetTo(, , ...
- 依赖作用域之<scope>test</scope>
经常在代码中看到依赖的作用域为<scope>test</scope>,它的作用是,只能在test目录(通过右键->Make Directory as->Test S ...
- P1004方格取数
这是提高组得一道动态规划题,也是学习y氏思考法的第一道题. 题意为给定一个矩阵,里面存有一些数,你从左上角开始走到右下角,另一个人从右下角开始走到左上角,使得两个人取数之和最大,当然一个数只可以取走一 ...
- 最长相同01数的子串(map搞搞)--牛客第三场 -- Crazy Binary String
题意: 如题. 或者用我的数组分治也可以,就是有点愚蠢. //#include <bits/stdc++.h> #include <map> #include <iost ...
- api返回数据
控制器里调用方法 <?php namespace app\admin\controller; use app\admin\controller\Base; class Index extends ...
- MySQL中的SQL的常见优化策略
MySQL中的SQL的常见优化策略 MySQL中的索引优化 MySQL中的索引简介 1 避免全表扫描对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索 ...