bzoj 1559 AC自动机 + dp
思路:直接在状态图上跑dp,最后枚举一下42种一下的。。 这个枚举有点恶心。
#include<bits/stdc++.h>
#define LL long long
#define ll long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg using namespace std; const int N = + ;
const int M = 1e7 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = ; int n, m, up, top, id[N], bord[N][N];
string s[], t[];
bool vis[N]; bool cmp(const string &a, const string &b) {
return a.size() > b.size();
}
bool check(const string &a, const string &b) {
for(int i = ; i < a.size(); i++) {
if(a.substr(i, b.size()) == b) return true;
}
return false;
} int cal(const string &a, const string &b) {
int l1 = a.size(), l2 = b.size();
for(int i = min(l1, l2) - ; i >= ; i--) {
if(a.substr(l1 - i, i) == b.substr(, i)) return i;
}
return ;
} struct Ac {
int ch[N][], val[N], f[N], tot, sz, depth[N];
LL dp[][][ << ];
Ac(int sz) {this->sz = sz;}
void init() {tot = ;};
int newNode() {
tot++; f[tot] = ; val[tot] = ;
memset(ch[tot], , sizeof(ch[tot]));
return tot;
}
inline int idx(char c) {return c - 'a';}
void addStr(string &s, int id) {
int u = ;
for(int i = ; i < s.size(); i++) {
int c = idx(s[i]);
if(!ch[u][c]) ch[u][c] = newNode(), depth[ch[u][c]] = depth[u] + ;
u = ch[u][c];
}
val[u] |= << id;
}
void build() {
queue<int> que;
for(int c = ; c < sz; c++) {
int v = ch[][c];
if(!v) ch[][c] = ;
else f[v] = , que.push(v);
}
while(!que.empty()) {
int u = que.front(); que.pop();
val[u] |= val[f[u]];
for(int c = ; c < sz; c++) {
int v = ch[u][c];
if(!v) ch[u][c] = ch[f[u]][c];
else f[v] = ch[f[u]][c], que.push(v);
}
}
} void solve() {
dp[][][] = ;
for(int k = ; k < n; k++) {
for(int u = ; u <= tot; u++) {
for(int c = ; c < sz; c++) {
int v = ch[u][c];
for(int s = ; s <= up; s++) {
dp[k + ][v][s | val[v]] += dp[k][u][s];
}
}
}
} LL ans = ;
for(int u = ; u <= tot; u++)
ans += dp[n][u][up];
cout << ans << '\n'; if(ans <= ) {
memset(vis, true, sizeof(vis));
sort(s, s + m, cmp);
for(int i = ; i < m; i++)
for(int j = i + ; j < m; j++)
if(check(s[i], s[j])) vis[j] = false; for(int i = ; i < m; i++)
if(vis[i]) id[top] = top, t[top++] = s[i]; for(int i = ; i < top; i++)
for(int j = ; j < top; j++)
if(i != j) bord[i][j] = cal(t[i], t[j]); vector<string> vec;
do {
string ret = t[id[]];
for(int i = ; i < top; i++) {
int len = bord[id[i - ]][id[i]];
ret += t[id[i]].substr(len, );
}
if(ret.size() == n) vec.push_back(ret);
} while(next_permutation(id, id + top)); sort(vec.begin(), vec.end());
for(int i = ; i < vec.size(); i++)
cout << vec[i] << '\n';
}
}
} ac(); int main() {
ac.init();
cin >> n >> m;
for(int i = ; i < m; i++) {
cin >> s[i];
ac.addStr(s[i], i);
}
up = ( << m) - ;
ac.build();
ac.solve();
return ;
} /*
*/
bzoj 1559 AC自动机 + dp的更多相关文章
- bzoj 1030 AC自动机+dp
代码: //先把给的单词建AC自动机并且转移fail,然后d[i][j]表示构造的文章到第i位时处在字典树的第j个节点的不包含单词的数量,最后用总的数量26^m //-d[m][0~sz]即可.其中不 ...
- [BZOJ 1559] [JSOI2009] 密码 【AC自动机DP】
题目链接:BZOJ - 1559 题目分析 将给定的串建成AC自动机,然后在AC自动机上状压DP. 转移边就是Father -> Son 或 Now -> Fail. f[i][j][k] ...
- [BZOJ 3530] [Sdoi2014] 数数 【AC自动机+DP】
题目链接:BZOJ - 3530 题目分析 明显是 AC自动机+DP,外加数位统计. WZY 神犇出的良心省选题,然而去年我太弱..比现在还要弱得多.. 其实现在做这道题,我自己也没想出完整解法.. ...
- bzoj 1030 [JSOI2007]文本生成器(AC自动机+DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1030 [题意] 给n个小串,随机构造一个长为m的大串,一个串合法当且仅当包含一个或多个 ...
- 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂
[题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...
- POJ1625 Censored!(AC自动机+DP)
题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...
- HDU2296 Ring(AC自动机+DP)
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- hdu 4117 GRE Words AC自动机DP
题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...
随机推荐
- ACM1881 01背包问题应用
01背包问题动态规划应用 acm1881毕业bg 将必须离开的时间限制看作背包容量,先将他们由小到大排序,然后在排完序的数组中对每个实例都从它的时间限制开始(背包容量)到它的延长时间进行遍历: #in ...
- Maven命令行窗口指定settings.xml
maven命令行窗口指定特定settings.xml 在命令行界面指定settings.xml,命令如下: mvn install --settings c:\user\settings.xml 例如 ...
- Lucene4.6至 Lucene6.6的每个迭代对API的改动
由于项目需求,需要将Lucene4.6升级到Lucene6.6,因此我对这之间的所有重要的API改动做了搜集:特别重要的改变加粗显示. Lucene4.7改动: LUCENE-5405: Make S ...
- Codeforces 713C Sonya and Problem Wihtout a Legend DP
C. Sonya and Problem Wihtout a Legend time limit per test 5 seconds memory limit per test 256 megaby ...
- python读文件和写入文件复习
with open("name.txt",'r') as read_file: for name in read_file: list_name = (name.split(',' ...
- 诱惑当前 你的孩子能hold住吗?
1.打好态度.动机.价值观基础 培养未成熟主体远大的志向,并不是向他们讲一些抽象的道理,而是根据他们的年龄特点,从形象的故事.童话开始,从身边的人物.事例出发,逐渐渗透一些人生的哲理.有一位自觉性非常 ...
- CODE FESTIVAL 2017 qual B C - 3 Steps
Score : 500 points Problem Statement Rng has a connected undirected graph with N vertices. Currently ...
- 【HDU】6012 Lotus and Horticulture (BC#91 T2)
[算法]离散化 [题解] 答案一定存在于区间的左右端点.与区间左右端点距离0.5的点上 于是把所有坐标扩大一倍,排序(即离散化). 让某个点的前缀和表示该点的答案. 初始sum=∑c[i] 在l[i] ...
- Part2-HttpClient官方教程-Chapter1-基础
前言 超文本传输协议(HTTP)可能是当今Internet上使用的最重要的协议.Web服务.网络支持的设备和网络计算的增长继续扩展了HTTP协议在用户驱动的Web浏览器之外的作用,同时增加了需要HTT ...
- [Leetcode Week12]Unique Paths
Unique Paths 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/unique-paths/description/ Description A ...