BZOJ1195 HNOI2006 最短母串
2016-02-24 19:23
399 查看
非主流做法 , 此题就不提示了。
看到此题 , Fuxey的第一感觉 , 这玩意我以前见过啊 , AC自动机上的动态规划。 中午回学校啪啪敲了一份AC自动机上的状压DP。
WA WA WA
然后检查 , 代码。 起初我认为同层(即同一个状态S) 互相影响并不会更优 , 所以不会影响答案, 然而需要考虑同层的转化。
不要紧 , Dijkstra上
TLE……
然而n^2的Dijkstra并不能过 , 优先队列优化一下呗。 然而A了……
(Fuxey建议大家还是写主流的状压DP写法 , 除非想练写AC自动机 )
附上最卡时限的数据:
TestData 9:
看到此题 , Fuxey的第一感觉 , 这玩意我以前见过啊 , AC自动机上的动态规划。 中午回学校啪啪敲了一份AC自动机上的状压DP。
WA WA WA
然后检查 , 代码。 起初我认为同层(即同一个状态S) 互相影响并不会更优 , 所以不会影响答案, 然而需要考虑同层的转化。
不要紧 , Dijkstra上
TLE……
然而n^2的Dijkstra并不能过 , 优先队列优化一下呗。 然而A了……
(Fuxey建议大家还是写主流的状压DP写法 , 除非想练写AC自动机 )
[code]#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #include <deque> #include <queue> #include <set> #include <map> #include <queue> #include <algorithm> #include <stack> #include <cassert> using namespace std; const int maxn = 12; const int maxlen = 51; const int sigmaSize = 26; const int INF = 0x3f3f3f3f; const int maxnode = maxlen*maxn; int n; char s[maxlen]; int d[maxnode][1<<maxn] , loop[maxnode][1<<maxn]; int pre[maxnode][1<<maxn]; __inline int id(char c) { return c-'A'; } struct ACaut { int n; queue<int> q; int g[maxnode][sigmaSize]; int mark[maxnode] , v[maxnode] , f[maxnode]; vector<int> l[maxnode] , r[maxnode]; int book[maxnode]; void init() { n = 0; } void add(int num) { int len = strlen(s) , u = 0; for(int i=0;i<len;i++) { int c = id(s[i]); if(!g[u][c]) { g[u][c] = ++n; mark = f = 0; memset(g , 0 , sizeof(g )); } u = g[u][c]; } mark[u] |= 1<<(num-1); } void getFail() { mark[0] = v[0] = f[0] = 0; for(int i=0;i<sigmaSize;i++) { int t = g[0][i]; if(!t) continue; q.push(t); if(mark[t]) v[t] = mark[t]; } while(!q.empty()) { int now = q.front(); q.pop(); for(int i=0;i<sigmaSize;i++) { int t = g[now][i] , j; if(!t) { g[now][i] = g[f[now]][i]; continue; } else q.push(t); for(j=f[now];j && !g[j][i];j = f[j]) ; f[t] = g[j][i]?g[j][i]:0; v[t] = v[f[t]]; if(mark[t]) v[t] |= mark[t]; } } } void dpInit() { for(int i=0;i<=n;i++) memset(d[i] , -1 , sizeof(d[i])); } void dp(int s) { if(s==(1<<::n)-1) { for(int i=0;i<=n;i++) d[i][s] = 0; return; } for(int i=0;i<=n;i++) l[i].clear() , r[i].clear(); for(int u=0;u<=n;u++) { int& now = d[u][s] = INF; book[u] = 0; for(int i=0;i<sigmaSize;i++) { int t = g[u][i]; if((s|v[t]) == s && t!=u) l[t].push_back(u) , r[t].push_back(i); else if(d[t][s|v[t]]+1 < now) now = d[t][s|v[t]]+1 , pre[u][s] = i; } } priority_queue<pair<int, int> > pq; for(int i=0;i<=n;i++) if(d[i][s]!=INF) pq.push(make_pair(-d[i][s], i)); while(pq.size()) { int now = pq.top().second , v = -pq.top().first; pq.pop(); if(d[now][s]!=v) continue; for(int i=0;i<l[now].size();i++) { int k = l[now][i]; if(d[k][s] > v+1 || (d[k][s]==v+1 && pre[k][s] > r[now][i])) { pre[k][s] = r[now][i]; if(d[k][s] == v+1) continue; d[k][s] = v+1; pq.push(make_pair(-d[k][s], k)); } } } } void print() { int s = 0; for(int i=0 , j=1;j<=d[0][0];j++) { printf("%c" , 'A'+pre[i][s]); i = g[i][pre[i][s]]; s |= v[i]; } } }solver; int main() { cin>>n; solver.init(); for(int i=1;i<=n;i++) { scanf("%s" , s); solver.add(i); } solver.getFail(); for(int i=(1<<n)-1;i>=0;i--) solver.dp(i); solver.print( ); return 0; }
附上最卡时限的数据:
TestData 9:
[code]Input: 12 AABBBABBBBBAAAAABABBBAAABBABBAABABAABAAABAAA AAABBBAAABABBBABBBABABAABAABABBBBABBBAABBA BBBBABAABABBBABABABBBAAABBABBBABAABBBAAABABBABB BABBBAABBABABBABBBAAABABAABBAA BBAABAAABAABBBBBABBBBBAABBBBABBBBBBABAAAAABAA ABAABBBBBABBAABAABBAAABABBBAAABBBBBABAAB ABBBBBABBAABAABBAAABABBBAAABBBBBABAABAAAAABBBBBAB BAAABABAABBAA BAABAAABABBBBBABBBABAAAAAABBAAABBBAAABABBB AAABABBABBBAAAABBBBAAAAABBBBABBBBABBAABAAABAAAB AAABABBBAAABBBBBABAABAAAAABBBBBABABABBAAABABAB BBAABBBBABABBAABABABBBBBBBBABAAABABAAAAA
[code]Output: BAABAAABABBBBBABBBABAAAAAABBAAABBBAAABABBBABBBABABAABAABABBBBABBBAABBABABBABBBAAABABAABBAABAAABAABBBBBABBBBBAABBBBABBBBBBABAAAAABAABBBBBABBAABAABBAAABABBBAAABBBBBABAABAAAAABBBBBABABABBAAABABABBAABBBBABABBAABABABBBBBBBBABAAABABAAAAABBBBABAABABBBABABABBBAAABBABBBABAABBBAAABABBABBBAAAABBBBAAAAABBBBABBBBABBAABAAABAAABBBABBBBBAAAAABABBBAAABBABBAABABAABAAABAAA
相关文章推荐
- MyCat - 源代码篇(6)
- MyCat - 源代码篇(6)
- MyCat - 源代码篇(6)
- 省选算法汇集(持续更新)最后更新2016.2.29
- 集中精力做最有价值的事情,而不必把主要精力都浪费在自我包装上(例如学位,头衔,自吹自擂)——沉痛反思:我以前还真是这样
- 设计模式的理解
- 给 Web 开发者的 25 款最有用的 AngularJS 工具
- viewpageindicator +fragment 在网络访问中与volley框架 null问题
- @RequestParam 和@RequestBody的使用方式
- AsyncTask实现的原理,和适用的优缺点
- 基于用户的协同过滤算法
- 约会代码= = 表示 自己都不知道咋对的
- 解决GitHub Pages屏蔽百度爬虫的方法
- POJ 3164 Command Network
- ReactiveCocoa框架菜鸟入门——信号(Signal)详解 第五课:适合给新手看的RAC用法总结
- (p143)11.1-4大数组直接寻址
- JavaSE程序分析002
- SAX DOM解析xml
- angluar根据链接的url参数的不同实现显示与隐藏
- CocoaAsyncSocket 与 Java服务 交互