题目链接:

https://codeforces.com/contest/1120/problem/C

题意:

从前往后压缩一段字符串

有两种操作:

1.对于单个字符,压缩它花费$a$

2.对于末尾一段字符串,如果这段字符串是已经压缩过字符串的子串,那么可以选择压缩它,花费为$b$

数据范围:

$1\leq |S| \leq 5000$

$1\leq a \leq 5000$

$1\leq b \leq 5000$

分析:

这道题目我们需要解决一个问题,计算某个子串出现的最早位置

转移,如果这个字串出现的最早位置不是当前位置,也就是说这个字串在前面还出现了一次,那么可以执行第二种操作

对于指定状态可以根据子状态转移,取最小的子状态的最早位置

给出子串下标求出子串出现的最早位置,首先得到子串在sam中的状态,根据状态得到最早出现的位置

AC代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5000+10;
char S[maxn];
int n,a,b;
struct suffixautomation
{
int mp[maxn*2][30],fa[maxn*2],ed,ct,len[maxn*2],minpos[maxn*2],deg[maxn*2],pos[maxn][maxn];
int dp[maxn];
suffixautomation(){ed=ct=1;}
inline void ins(int c,int pos)
{
int p=ed;ed=++ct;minpos[ed]=pos;len[ed]=pos;//先初始化size和len
for(;p&&mp[p][c]==0;p=fa[p]){mp[p][c]=ed;}//然后顺着parent树的路径向上找
if(p==0){fa[ed]=1;return;}int q=mp[p][c];//case1
if(len[p]+1==len[q]){fa[ed]=q;return;}//case2
len[++ct]=len[p]+1;//case 3
for(int i=1;i<=26;i++){mp[ct][i]=mp[q][i];}
fa[ct]=fa[q];fa[q]=ct;fa[ed]=ct;
for(int i=p;mp[i][c]==q;i=fa[i]){mp[i][c]=ct;}
}
void solve(){
for(int i=1;i<=n;i++){
int now=1;
for(int j=i;j<=n;j++){
int v=S[j]-'a'+1;
now=mp[now][v];
pos[i][j]=now;
}
}
for(int i=1;i<=ct;i++)deg[fa[i]]++;
queue<int>que;
for(int i=1;i<=ct;i++)if(deg[i]==0)que.push(i);
while(que.size()){
int x=que.front();
int y=fa[x];
que.pop();
minpos[y]=min(minpos[x],minpos[y]);
deg[y]--;
if(deg[y]==0)que.push(y);
}
for(int i=1;i<=n;i++){
dp[i]=dp[i-1]+a;
for(int j=2;j<=i;j++){
if(minpos[pos[j][i]]<j){
dp[i]=min(dp[i],dp[j-1]+b);
break;
}
}
}
printf("%d\n",dp[n]); }
}sam;
int main()
{
scanf("%d %d %d",&n,&a,&b);
scanf("%s",S+1);
for(int i=0;i<maxn*2;i++)sam.minpos[i]=1e9;
for(int i=1;i<=n;i++)sam.ins(S[i]-'a'+1,i);
sam.solve();
return 0;
}

  

codeforces#1120C. Compress String(dp+后缀自动机)的更多相关文章

  1. Codeforces 1120C Compress String(DP)

    题意:给你一个字符串,有2种消除方式:1:消除一个单独的字母,代价为a.2:s[j]到s[k]是s[1]到s[j - 1]的子串,那么s[j]到s[k]可以消除,代价为b,问最小的代价. 思路:官方题 ...

  2. 【Hihocoder1413】Rikka with String(后缀自动机)

    [Hihocoder1413]Rikka with String(后缀自动机) 题面 Hihocoder 给定一个小写字母串,回答分别把每个位置上的字符替换为'#'后的本质不同的子串数. 题解 首先横 ...

  3. 【计蒜客】是男人就过 8 题--Pony.AI 题 A. A String Game 后缀自动机+SG函数

    [题目]A. A String Game [题意]给定目标串S和n个子串Ti,Alice和Bob轮流选择一个子串操作,必须且只能在子串末尾添加一个字符使得新串也是S的子串,不能操作即输,求胜利者.|S ...

  4. HDU6583:Typewriter(dp+后缀自动机)

    传送门 题意: 给出\(p,q\),现在要你生成一个字符串\(s\). 你可以进行两种操作:一种是花费\(p\)的代价随意在后面添加一个字符,另一种是花费\(q\)的代价可以随意赋值前面的一个子串. ...

  5. BZOJ 2806: [Ctsc2012]Cheat(单调队列优化dp+后缀自动机)

    传送门 解题思路 肯定先要建出来广义后缀自动机.刚开始以为是个二分+贪心,写了一下结果\(20\)分.说一下正解,首先显然\(L_0\)具有单调性,是可以二分的.考虑二分后怎样判合法,对于分割序列很容 ...

  6. hdu多校第一场 1006 (hdu6583)Typewriter dp/后缀自动机

    题意: 有个打字机,在当前字符串后新加一个字花费p,把当前字符串的一个连续子串拷贝到当前字符串的末尾花费q,给定一个字符串,求用打字机打出这个字符串的最小花费. 题解: 容易想到用dp 记dp[i]为 ...

  7. BZOJ5408: string(广义后缀自动机,LCT)

    传送门 解题思路: 首先在后缀树上,确定了一个节点就相当于确定了一个串,那么一个点对应的串在另外一个点对应的串产生贡献,当且仅当这个点在当前点子树内. 那么考虑一个新的点在串中对串答案的贡献在一条树链 ...

  8. Codeforces 1050D Three Religions (dp+序列自动机)

    题意: 给一个1e5的串str,然后有三个起始空串,不超过1000次操作,对三个字符串的一个尾部加一个字符或者减一个字符,保证每个字符不会超过250 每次操作之后询问你这三个串是不是可以组成str的子 ...

  9. BZOJ.4032.[HEOI2015]最短不公共子串(DP 后缀自动机)

    题目链接 1.求A的最短子串,它不是B的子串. 子串是连续的,对B建SAM,枚举起点,在SAM上找到第一个无法匹配点即可.O(n)用SAM能做吗..开始想错了. 2.求A的最短子串,它不是B的子序列. ...

随机推荐

  1. SQL Server的非聚集索引中会存储NULL吗?

    原文:SQL Server的非聚集索引中会存储NULL吗? SQL Server的非聚集索引中会存储NULL吗? 这是个很有意思的问题,下面通过如下的代码,来说明,到底会不会存储NULL. --1.建 ...

  2. java中的权限修饰符&关键字

    1.类的权限修饰符default(不写权限修饰符),public 说明:类的权限修饰符只有default(不写权限修饰符)和public.   package world default Y N pu ...

  3. netcat瑞士军刀实现电脑远程控制termux

    关于nc实现远程控制termux 1.首先termux安装namp pkg install namp 2.windows系统安装netcat 此为netcat下载连接 下载得到zip压缩包,解压得到里 ...

  4. 使用 rm -rf 删除了工程目录,然后从 pycharm 中找了回来

    一次惊险的 rm -rf 操作,以后删东西真的要小心,慢点操作 前两天周 4 周 5,写了两天的 python 代码没有提交,昨天晚上删日志目录,先跨目录查看了下日志目录的列表情况:ll ~/logs ...

  5. Windows cmd操作文件夹

    ir // 列出目录下所有文件夹 rd dirname // 删除dirname文件夹(空文件夹) rd /s/q dirname // 删除dirname文件夹(非空)

  6. HTML5 - 初识

    众所周知,我们现在的手机APP开发模式分为一下几大类: 一.原生APP 二.纯HTML5 三.原生+HTML5 四.React Native 公司的职位划分: 1.平面设计师  : 作图.切图.HTM ...

  7. kubeadm init初始化报错解决,亲测

    [preflight] You can also perform this action in beforehand using 'kubeadm config images pull' error ...

  8. C#-调试记Log文件

    using System.IO; //捕获异常写入Log catch (Exception ex) { string msg = ex.Message + ex.StackTrace; string ...

  9. Android笔记(二十七) Android中的动态广播和静态广播

    广播接收器注册一共有两种形式 : 静态注册和动态注册. 两者及其接收广播的区别: 1.动态注册的广播 永远要快于 静态注册的广播,不管静态注册的优先级设置的多高,不管动态注册的优先级有多低>\ ...

  10. 运维开发笔记整理-Request对象与Response对象

    运维开发笔记整理-Request对象与HttpResponse对象 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.request对象 1>.什么是request 首先,我 ...