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 ...
随机推荐
- YAML基础知识及搭建一台简洁版guestbook
一,前言 前面我们已经搭建过简易版k8s集群了,在此基础上可以搭建一个简洁版guestbook ,以便来学习k8s创建pod的整个过程. 二,在此之前,我们还需要学习一下YAML基础知识 YAML 基 ...
- Tensorflow 保存和载入训练过程
本节涉及点: 保存训练过程 载入保存的训练过程并继续训练 通过命令行参数控制是否强制重新开始训练 训练过程中的手动保存 保存训练过程前,程序征得同意 一.保存训练过程 以下方代码为例: import ...
- HNU_团队项目_数据库设计感想_个人感想
数据库设计感想 个人的一点心得体会 最重要的放在最前面——讨论开会时的123经验 开会前对会议目的及方式要有所考虑: 不要随意无目的开会: 遵守时间,控制会议时间长度: 会议主持人要维持会议只需,有 ...
- flask 之(六) --- API|RestfulApi
接口概念 IOP:面向接口编程,不再关注具体的实现:只关注输入.输出. http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practice ...
- HCL试验5
PC端配置:配置ip地址 交换机1配置:①创建VLAN system-view vlan 10 vlan 20 ②配置PC端接口 interface gi 1/0/1 port link-type a ...
- Django视图之FBV与CBV
一. CBV与FBV CBV:Class Based View FBV:Function Based View 我们之前写过的都是基于函数的view,就叫FBV.还可以把view写成基于类的,那就是C ...
- 白盒测试笔记之:testng 单元测试
前言 前一篇文章我们简单了解了下单元测试的概念以及使用junit进行入门了. 但想更好做自动化测试,还是得了解下testng,毕竟,作为一名技术人,NG(下一代)的测试框架总得了解与跟进. testn ...
- Java中流的操作练习
文件中的学生信息 学生信息存储在TXT文件中,我们需要对信息进行基本的,增.删.改.查,全部显示操作. 1.学生类/Student package com.yujiao.student; public ...
- [转帖]RPM的原理及rpm命令常用参数
RPM的原理及rpm命令常用参数 2015年09月14日 15:39:43 lose_wait 阅读数 1298 https://blog.csdn.net/u012012939/article/de ...
- IDEA项目目录里下找不到src,但是src确实存在的的解决方案
写代码的时候可能出现写着写着src就找不到了,我个人认为是触发了热键导致src被隐藏了,下面就是设置src可见和不可见的操作 这个其实是被隐藏了,打开就好,位置如下: