题面 传送门 思路 首先,有一个非常显然的思路就是dp: 设$dp[i][j]$表示前i个字符,最后一个为j 然后发现这个东西有后效性 改!设$dp[i][j]$代表前i个字符,最后15个的状态为j(压缩一下),转移的是候枚举增加那个字符,然后看从谁可以推过来 然后就TLE了,完全无压力 怎么优化这个算法? 显然,枚举完增加哪个字符以后,可以用AC自动机来实现多模匹配 然后发现:我们把j的定义变成AC自动机上面的点j,这样一个点就代表一种状态,状态之间互相不重复,而且也没有后效性 这样的定义方法…
Description 贝西正在打格斗游戏.游戏里只有三个按键,分别是“A”.“B”和“C”.游戏中有 N 种连击 模式,第 i 种连击模式以字符串 Si 表示,只要贝西的按键中出现了这个字符串,就算触发了一次连 击模式.不 同的连击模式是独立计算的,如果几个连击模式同时出现在贝西的按键顺序里,就算有重 叠部分, 也可以同时算作触发了多个模式. 假如有三个连击模式,分别是“AB”,“BA”,“ABC”,而贝西按下了“ABABC”,那么她一共 触发了四次 连击.假设贝西一共可以按 K 次键,那么她…
正解:AC自动机+dp 解题报告: 传送门! 算是个比较套路的AC自动机+dp趴,,, 显然就普普通通地设状态,普普通通地转移,大概就f[i][j]:长度为i匹配到j 唯一注意的是,要加上所有子串的贡献,就在结构体中新加一个变量d表示在跟到这个节点的串以及后缀中完整串的个数 直接在bfs求fail的时候加上fail指针的d就欧克 啊当然只是为了方便描述所以说另开一个d,,,实际实现的话直接把标记结尾的那个值改成int类型搞下就欧克 然后说下细节,,, 其实就一个细节,就赋初值问题,要把除了f[i…
题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后缀状态为自动机第j个结点的合法字符串数 dp[0][0]=1 转移转移... 注意要用高精度,因为答案最多5050. 还有就是要用unsigned char,题目的输入居然有拓展的ASCII码,编码128-255. #include<cstdio> #include<cstring>…
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个字符数组记录每个状态最优情况的字符串即可. 另外题目字典序是先考虑长度再考虑每一位单词:特别要注意,有一个非常坑的地方看了Disscus才知道——单词A包含单词B,那么只计算单词A不计算单词B. dp[i][j]表示长度i(自动机上转移k步)后缀状态是自动机第j个结点的字符串的最大价值 dp[0][…
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步)且后缀状态为AC自动机结点j的最少需要修改的基因数 转移我为人人型,从dp[i][j]向ATCG四个方向转移到dp[i+1][j'],如果结点被标记包含致病基因就不能转移. #include<cstdio> #include<cstring> #include<queue>…
题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多. 对于这题来说,需要离线操作.dp转移也是很显然. 但是由于数据比较大,所以普通的沿着fail指针往上走,逐步更新答案会TLE. 考虑把fail指针反向,由于ac自动机的每个节点均有唯一的fail指针,若是沿着fail指针往上走,显然都会走到root,所以反向之后显然是一棵树,不妨称之为fail树…
题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #include<stdlib.h> #include<iostream> #include<queue> using namespace std; struct node{ ]; int fail; int flag; void init() { memset(next,,si…
DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 940    Accepted Submission(s): 500 Problem Description Biologists finally invent techniques of repairing DNA that contains segments cau…
题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小的. 题解:AC自动机+dp.dp[i][j]表示在字符串长度i,在自动机的第j个状态.因为要字典序最小,所以转移时要保持字典序最小. 想了各种转移姿势 最后还是查了题解 发现可以直接记录前缀转移…… #include <bits/stdc++.h> using namespace std; ;…