[BZOJ1195][HNOI2006]最短母串(状压DP)
来源:互联网 发布:java velocity 编辑:程序博客网 时间:2024/06/04 19:14
首先,去除一些没有用的串。
也就是说,如果存在两个串
然后预处理出
DP模型:
代码(微恶心):
#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 14, M = 53, R = 605, C = (1 << 12) + 5, INF = 0x3f3f3f3f;int n, nxt[M], len[N], tmp[N], f[C][N], con[N][N];char s[N][M], ts[N][M];bool vis[N]; string st[N][M], str[C][N];bool check(int x, int y) { int i, j = 0; nxt[1] = 0; for (i = 2; i <= len[y]; i++) { while (j && s[y][i] != s[y][j + 1]) j = nxt[j]; if (s[y][i] == s[y][j + 1]) j++; nxt[i] = j; } j = 0; for (i = 1; i <= len[x]; i++) { while (j && s[x][i] != s[y][j + 1]) j = nxt[j]; if (s[x][i] == s[y][j + 1]) j++; if (j == len[y]) return 1; } return 0;}bool check2(int x, int y, int p) { int i; for (i = len[x] - p + 1; i <= len[x]; i++) if (s[x][i] != s[y][i + p - len[x]]) return 0; return 1;}void DP() { int i, j, k, Cm = 1 << n; for (i = 1; i < Cm; i++) for (j = 1; j <= n; j++) { if (!((i >> j - 1) & 1)) continue; if (!(i & (i - 1))) { f[i][j] = len[j]; str[i][j] = st[j][1]; continue; } f[i][j] = INF; string tm(600, 'Z'); str[i][j] = tm; for (k = 1; k <= n; k++) { if ((!((i >> k - 1) & 1)) || j == k) continue; int S = i ^ (1 << j - 1), le = f[S][k] + len[j] - con[k][j]; if (le < f[i][j] || (le == f[i][j] && (str[S][k] + st[j][con[k][j] + 1]) < str[i][j])) f[i][j] = le, str[i][j] = str[S][k] + st[j][con[k][j] + 1]; } } int res = INF; string zz(600, 'Z'); for (i = 1; i <= n; i++) if (f[Cm - 1][i] < res || (f[Cm - 1][i] == res && str[Cm - 1][i] < zz)) res = f[Cm - 1][i], zz = str[Cm - 1][i]; cout << zz << endl;}int main() { int i, j, k, tot = 0; scanf("%d", &n); for (i = 1; i <= n; i++) scanf("%s", s[i] + 1), len[i] = strlen(s[i] + 1); for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) { if (i == j) continue; if (check(i, j) && (len[i] != len[j] || (len[i] == len[j] && i < j))) vis[j] = 1; } for (i = 1; i <= n; i++) { if (vis[i]) continue; tot++; for (j = 1; j <= len[i]; j++) ts[tot][j] = s[i][j]; tmp[tot] = len[i]; } n = tot; for (i = 1; i <= n; i++) { for (j = 1; j <= tmp[i]; j++) s[i][j] = ts[i][j]; len[i] = tmp[i]; } for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) for (k = 1; k < min(len[i], len[j]); k++) if (check2(i, j, k)) con[i][j] = k; for (i = 1; i <= n; i++) for (j = 1; j <= len[i]; j++) { string tm(len[i] - j + 1, 'A'); for (k = j; k <= len[i]; k++) tm[k - j] = s[i][k]; st[i][j] = tm; } return DP(), 0;}
此外,此题的AC自动机解法参考链接:http://wyfcyx.is-programmer.com/posts/76627.html。
阅读全文
0 0
- [BZOJ1195] [HNOI2006]最短母串(状压dp)
- [BZOJ1195][HNOI2006]最短母串(状压DP)
- BZOJ1195 HNOI2006 最短母串
- bzoj1195: [HNOI2006]最短母串
- 【HNOI2006】bzoj1195 最短母串
- 【bzoj1195】[HNOI2006]最短母串
- bzoj 1195: [HNOI2006]最短母串 (状压dp)
- bzoj1195(最短母串)
- BZOJ 1195 [HNOI2006]最短母串 状压DP
- bzoj 1195: [HNOI2006]最短母串 状压dp
- BZOJ 1195: [HNOI2006]最短母串
- 2782: [HNOI2006]最短母串
- BZOJ 1195 [HNOI2006] 最短母串
- bzoj 1195 [HNOI2006]最短母串
- 【bzoj1197】【HNOI2006】【花仙子的魔法】【dp】
- 大视野1195: [HNOI2006]最短母串
- 【33.28%】【BZOJ 1195】[HNOI2006]最短母串
- 洛谷P2322 [HNOI2006]最短母串问题
- adb的使用注意
- WOJ-287 商人会议
- Java基础之集合框架--Collections.binarySearch()
- Java:笔记随笔2
- 中继点
- [BZOJ1195][HNOI2006]最短母串(状压DP)
- 大数据入门
- Springboot系列:Springboot与Thymeleaf模板引擎整合基础教程(附源码)
- Sicily.1021 Couples
- 迭代器的使用
- 极小开发团队构建
- caffe2之caffe_translator
- Python做字符串处理
- [maven(1)]myeclipse2014下如何配置maven