题目链接:

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. SSH安全加固

    SSH安全加固 配置文件: /etc/ssh/sshd_config # This file is automatically generated at startup KexAlgorithms c ...

  2. docker第二章--数据管理

  3. nginx 反向代理配置(一)

    文章参考:https://blog.csdn.net/physicsdandan/article/details/45667357       什么是代理?       代理在普通生活中的意义就是本来 ...

  4. RocketMQ——角色与术语详解

    原文地址:http://jaskey.github.io/blog/2016/12/15/rocketmq-concept/ RocketMQ——角色与术语详解 2016-12-15 THU 15:4 ...

  5. 关于MQ的几件小事(一)消息队列的用途、优缺点、技术选型

    1.为什么使用消息队列? (1)解耦:可以在多个系统之间进行解耦,将原本通过网络之间的调用的方式改为使用MQ进行消息的异步通讯,只要该操作不是需要同步的,就可以改为使用MQ进行不同系统之间的联系,这样 ...

  6. C#一些不太熟悉的类——扩展学习

    Process.CloseMainWindow Method 通过向进程的主窗口发送关闭消息来关闭拥有用户界面的进程. 注解 进程执行时,其消息循环处于等待状态. 每次操作系统将 Windows 消息 ...

  7. 请求类型 GET 和 POST 的区别

    一.GET 一个简单的 GET 请求: xmlhttp.open("GET","demo_get.asp",true); xmlhttp.send(); 在上面 ...

  8. 2星|项立刚《5G时代》:资料堆砌和一些假想设想,信息浓度太低

    “ 这是一本关于5G的书,但着眼点不是要说清楚5G的技术,因为解读5G技术的图书已经有很多,我自己也不是技术专家.本书是希望探讨在一个全新的网络体系下产业的发展与改变,以及5G对社会与经济的影响.P6 ...

  9. reverse函数的实现

    用递归的方法实现字符串的倒叙 #include <string.h> void reverse_my(char *a,int len) { int tmp;//中间值 if(len < ...

  10. python_面向对象——属性方法property

    1.属性方法 class Student(object): def __init__(self,name): self.name = name @property #属性方法:把一个方法变成一个静态的 ...