题目链接

题意:你要打印一段字符串,往尾部添加一个字符需要花费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)的更多相关文章

  1. HDU 6583 Typewriter(后缀自动机)

    Typewrite \[ Time Limit: 1500 ms\quad Memory Limit: 262144 kB \] 题意 给出一个字符串 \(s\),现在你需要构造出这个字符串,你每次可 ...

  2. 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp

    题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...

  3. 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 ...

  4. HDU 6583 Typewriter 题解

    ——本题来自杭电多校第一场 题意:给定一个字符串,主角需要用打字机将字符串打出来,每次可以: 1.花费p来打出任意一个字符 2.花费q来将已经打出的某一段(子串)复制到后面去 对于这种最优化的问题,我 ...

  5. bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP

    2806: [Ctsc2012]Cheat Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 583  Solved: 330[Submit][Statu ...

  6. fjwc2019 D1T2 原样输出(后缀自动机+dp)

    #179. 「2019冬令营提高组」原样输出 暴力对每个串建后缀自动机,然后暴力枚举每个自动机的子串.可以拿到部分分. 然鹅我们可以把每个后缀自动机连起来. 我们知道,后缀自动机是用最少的点(空间)表 ...

  7. 【BZOJ3238】差异【后缀自动机+dp】

    题意 分析 这个题目还是很优秀的.sigma(len(Ti)+len(Tj))的值是一定的=n*(n+1)*(n-1)/2.那么关键就是求任意两个后缀的lcp的和了. 我们怎么求两个后缀的lcp?如果 ...

  8. 【SPOJ - SUBLEX】Lexicographical Substring Search 【后缀自动机+dp】

    题意 给出一个字符串和q个询问,每个询问给出一个整数k,输出第k大得子串. 分析 建后缀自动机,利用匹配边来解决.设d[v]为从状态v开始有多少不同的路径.这个显然是可以递推出来的.然后对于每个询问, ...

  9. 【SPOJ -NSUBSTR】Substrings 【后缀自动机+dp】

    题意 给出一个字符串,要你找出所有长度的子串分别的最多出现次数. 分析 我们建出后缀自动机,然后预处理出每个状态的cnt,cnt[u]指的是u这个状态的right集合大小.我们设f[len]为长度为l ...

随机推荐

  1. YAML基础知识及搭建一台简洁版guestbook

    一,前言 前面我们已经搭建过简易版k8s集群了,在此基础上可以搭建一个简洁版guestbook ,以便来学习k8s创建pod的整个过程. 二,在此之前,我们还需要学习一下YAML基础知识 YAML 基 ...

  2. Tensorflow 保存和载入训练过程

    本节涉及点: 保存训练过程 载入保存的训练过程并继续训练 通过命令行参数控制是否强制重新开始训练 训练过程中的手动保存 保存训练过程前,程序征得同意 一.保存训练过程 以下方代码为例: import ...

  3. HNU_团队项目_数据库设计感想_个人感想

    数据库设计感想  个人的一点心得体会 最重要的放在最前面——讨论开会时的123经验 开会前对会议目的及方式要有所考虑: 不要随意无目的开会: 遵守时间,控制会议时间长度: 会议主持人要维持会议只需,有 ...

  4. flask 之(六) --- API|RestfulApi

    接口概念 IOP:面向接口编程,不再关注具体的实现:只关注输入.输出. http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practice ...

  5. HCL试验5

    PC端配置:配置ip地址 交换机1配置:①创建VLAN system-view vlan 10 vlan 20 ②配置PC端接口 interface gi 1/0/1 port link-type a ...

  6. Django视图之FBV与CBV

    一. CBV与FBV CBV:Class Based View FBV:Function Based View 我们之前写过的都是基于函数的view,就叫FBV.还可以把view写成基于类的,那就是C ...

  7. 白盒测试笔记之:testng 单元测试

    前言 前一篇文章我们简单了解了下单元测试的概念以及使用junit进行入门了. 但想更好做自动化测试,还是得了解下testng,毕竟,作为一名技术人,NG(下一代)的测试框架总得了解与跟进. testn ...

  8. Java中流的操作练习

    文件中的学生信息 学生信息存储在TXT文件中,我们需要对信息进行基本的,增.删.改.查,全部显示操作. 1.学生类/Student package com.yujiao.student; public ...

  9. [转帖]RPM的原理及rpm命令常用参数

    RPM的原理及rpm命令常用参数 2015年09月14日 15:39:43 lose_wait 阅读数 1298 https://blog.csdn.net/u012012939/article/de ...

  10. IDEA项目目录里下找不到src,但是src确实存在的的解决方案

    写代码的时候可能出现写着写着src就找不到了,我个人认为是触发了热键导致src被隐藏了,下面就是设置src可见和不可见的操作 这个其实是被隐藏了,打开就好,位置如下: