有方程dp[i]=min(dp[i-1]+A,dp[j]+B);如果s[j+1,i]在s[i,j]中出现,所以我们就是要知道每个子串在s出现的第一个位置,这个可以hash实现或者sam,或者kmp实现。

pos[i][j]表示s[i,j]对应的sam的位置,occ[],表示第一次出现的位置。

#include<bits/stdc++.h>
#define ll long long
#define rep2(i,a,b) for(int i=a;i>=b;i--)
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
char c[maxn],s[maxn];
struct SAM{
int ch[maxn][],fa[maxn],maxlen[maxn],cnt,last;
int a[maxn],b[maxn],occ[maxn];
void init()
{
cnt=last=;
memset(ch[],,sizeof(ch[]));
memset(occ,0x3f,sizeof(occ));
}
int add(int x,int pos)
{
int np=++cnt,p=last; last=np; occ[np]=pos;
maxlen[np]=maxlen[p]+;memset(ch[np],,sizeof(ch[np]));
while(p&&!ch[p][x]) ch[p][x]=np,p=fa[p];
if(!p) fa[np]=;
else {
int q=ch[p][x];
if(maxlen[q]==maxlen[p]+) fa[np]=q;
else {
int nq=++cnt; maxlen[nq]=maxlen[p]+;
fa[nq]=fa[q]; fa[q]=fa[np]=nq;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
while(p&&ch[p][x]==q) ch[p][x]=nq,p=fa[p];
}
}
}
void Sort()
{
rep(i,,cnt) a[i]=;
rep(i,,cnt) a[maxlen[i]]++;
rep(i,,cnt) a[i]+=a[i-];
rep(i,,cnt) b[a[maxlen[i]]--]=i;
for(int i=cnt;i>=;i--)
occ[fa[b[i]]]=min(occ[b[i]],occ[fa[b[i]]]);
}
}T;
int a[maxn],A,B,dp[maxn],pos[][];
int main()
{
int N;
scanf("%d%d%d%s",&N,&A,&B,c+);
T.init();
rep(i,,N) T.add(c[i]-'a',i);
rep(i,,N) {
int now=;
rep(j,i,N){
now=T.ch[now][c[j]-'a'];
pos[i][j]=now;
}
}
T.Sort();
rep(i,,N){
dp[i]=dp[i-]+A;
rep(j,,i-){
if(T.occ[pos[j+][i]]<=j){
dp[i]=min(dp[i],dp[j]+B);
break;
}
}
}
printf("%d\n",dp[N]);
return ;
}

CF1120 C. Compress String(SAM+DP)的更多相关文章

  1. NYOJ 1067 Compress String(区间dp)

    Compress String 时间限制:2000 ms  |  内存限制:65535 KB 难度:3 描写叙述 One day,a beautiful girl ask LYH to help he ...

  2. spoj 1812 LCS2(SAM+DP)

    [题目链接] http://www.spoj.com/problems/LCS2/en/ [题意] 求若干个串的最长公共子串. [思路] SAM+DP 先拿个串建个SAM,然后用后面的串匹配,每次将所 ...

  3. hdu_3336: Count the string(KMP dp)

    题目链接 题意:求给定字符串中,可以与某一前缀相同的所有子串的数量 做这道题需要明白KMP算法里next[]数组的意义 首先用一数组nex[](这里与之前博客中提到的next明显不同)存储前缀后缀最长 ...

  4. hdu 3336 count the string(KMP+dp)

    题意: 求给定字符串,包含的其前缀的数量. 分析: 就是求所有前缀在字符串出现的次数的和,可以用KMP的性质,以j结尾的串包含的串的数量,就是next[j]结尾串包含前缀的数量再加上自身是前缀,dp[ ...

  5. 【HDU 3336】Count the string(KMP+DP)

    Problem Description It is well known that AekdyCoin is good at string problems as well as number the ...

  6. [HAOI2016]找相同字符(SAM+DP)

    感觉很水. 因为SAM上一个点的子树大小代表这个点所表示子串的出现次数. 建出广义后缀自动机之后.在\(parent\)树上跑\(DP\),维护\(size[i][1]\),和\(size[i][0] ...

  7. F. Clear the String(区间 DP )//每次都删除一个相同字符的子串 , 最小多少次

    https://codeforces.com/contest/1132/problem/F 借鉴:https://www.cnblogs.com/chhokmah/p/10508762.html 题意 ...

  8. 2018.12.12 codeforces 931E. Game with String(概率dp)

    传送门 感觉这题难点在读懂题. 题目简述:给你一个字符串s,设将其向左平移k个单位之后的字符串为t,现在告诉你t的第一个字符,然后你可以另外得知t的任意一个字符,求用最优策略猜对k的概率. 解析: 预 ...

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

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

随机推荐

  1. 【HTTP】boundary 中一个 = 导致HTTP上传文件失败

    (1)#define ABOUNDARY "----=_Resume_002_0CE7_01D1C649.298A8070" (2)#define ABOUNDARY " ...

  2. nyoj-0708-ones(dp)

    nyoj-0708-ones 题意:用1,+,*,(,). 这四个符号组成表达式表达数s(0 <= s <= 10000),且1最少时1的的个数 状态转移方程: dp[i] = min(d ...

  3. laravel的日志服务

    日志服务使用: $app=app(); $log=$app->make('log'); $log->info('post_index',['data'=>'this is post ...

  4. bzoj1294

    题解: 首先发现假如一个豆豆被多边形围住了,那么从这个豆豆引出一条射线 会有奇数个焦点 然后我们从每个豆豆引出一条射线 然后状压dfs 代码: #include<bits/stdc++.h> ...

  5. new_images

    /home/westward/Pictures/Screenshot from 2017-03-19 20:23:55.png

  6. 如何写java求和源代码

    1.设计思想:利用eclipse编写. 2.程序流程图:先建立一个包->建立一个类->写代码->运行->修正错误,完善代码. 3.源程序代码: package dijia; p ...

  7. delete和delete[] 区别

    // DeleteAndDelete[].cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h> ...

  8. MPX

    Pre-processing: MPX使用的滤波器是自适应性的‘Wiener’ filter.有时甚至不用MPX,因为尽管Wiener 所引起的扰乱是可以忽略的,有时发现滤波并不能很好地提高拾取的精度 ...

  9. POJ - 1850 B - Code

    Transmitting and memorizing information is a task that requires different coding systems for the bes ...

  10. 牛客练习赛22 简单瞎搞题(bitset优化dp)

    一共有 n个数,第 i 个数是 xi  xi 可以取 [li , ri] 中任意的一个值. 设 ,求 S 种类数. 输入描述: 第一行一个数 n. 然后 n 行,每行两个数表示 li,ri.   输出 ...