思路:好像以前谁问过我这题。。。  状个压就好啦, 把包含在其他串中的字符串删掉, 预处理除每两个字符串之间的关系,

dp[ state ][ i ] 表示在state的状态下, 最后一个字符串是第i个的最优解, 字典序最小的话暴力把转移过程中的字符串存下来

就好啦。

 #include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int,int>
#define piii pair<int, pair<int,int>> using namespace std; const int N=+;
const int M=1e4+;
const int inf=0x3f3f3f3f;
const LL INF=0x3f3f3f3f3f3f3f3f;
const int mod=1e9 + ; int n, top, up, cost[][], len[], ret[], dp1[ << ][];
string s[], t[], dp2[ << ][]; int cal(string &a, string &b, int len1, int len2) {
for(int i = max(, len2 - len1); i < len2; i++) {
bool flag = true;
for(int j = i, k = ; j < len2; j++, k++) {
if(b[j] != a[k]) {
flag = false;
break;
}
}
if(flag) {
return len1 - (len2 - i);
}
}
return len1;
} bool check(string &t) {
for(int i = ; i < top; i++) {
for(int j = ; j < s[i].size(); j++) {
string ret = s[i].substr(j, t.size());
if(ret == t) return false;
}
}
return true;
} bool cmp(const string &a, const string &b) {
return a.size() > b.size();
}
int main() {
memset(dp1, inf, sizeof(dp1));
scanf("%d", &n);
for(int i = ; i < n; i++) {
cin >> t[i];
} sort(t, t + n, cmp); for(int i = ; i < n; i++) {
if(check(t[i])) {
s[top++] = t[i];
}
} n = top; up = << n; for(int i = ; i < n; i++)
len[i] = s[i].size(); for(int i = ; i < n; i++) {
for(int j = ; j < n; j++) {
if(i == j) continue;
cost[i][j] = cal(s[i], s[j], len[i], len[j]);
}
} for(int i = ; i < n; i++) {
dp1[ << i][i] = len[i];
dp2[ << i][i] = s[i];
} for(int state = ; state < up; state++) {
for(int i = ; i < n; i++) {
if(dp1[state][i] == inf)
continue;
for(int j = ; j < n; j++) {
if((state >> j) & ) continue;
if(dp1[state ^ ( << j)][j] > dp1[state][i] + cost[j][i]) {
dp1[state ^ ( << j)][j] = dp1[state][i] + cost[j][i];
dp2[state ^ ( << j)][j] = dp2[state][i] + s[j].substr(len[j] - cost[j][i], cost[j][i]);
} else if(dp1[state ^ ( << j)][j] == dp1[state][i] + cost[j][i]) {
string ret = dp2[state][i] + s[j].substr(len[j] - cost[j][i], cost[j][i]);
if(ret < dp2[state ^ ( << j)][j])
dp2[state ^ ( << j)][j] = dp2[state][i] + s[j].substr(len[j] - cost[j][i], cost[j][i]);
}
}
}
} int id = ; for(int i = ; i < n; i++) {
if(dp1[up - ][i] < dp1[up - ][id]) {
id = i;
} else if(dp1[up - ][i] == dp1[up - ][id] && dp2[up - ][i] < dp2[up - ][id]) {
id = i;
}
} cout << dp2[up - ][id] << endl;
return ;
}
/*
*/

1195: [HNOI2006]最短母串的更多相关文章

  1. bzoj 1195: [HNOI2006]最短母串 爆搜

    1195: [HNOI2006]最短母串 Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 894  Solved: 288[Submit][Status] ...

  2. BZOJ 1195: [HNOI2006]最短母串

    1195: [HNOI2006]最短母串 Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1346  Solved: 450[Submit][Status ...

  3. 【状态压缩dp】1195: [HNOI2006]最短母串

    一个清晰的思路就是状压dp:不过也有AC自动机+BFS的做法 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T ...

  4. bzoj 1195 [HNOI2006]最短母串 bfs 状压 最短路 AC自动机

    LINK:最短母串 求母串的问题.不适合SAM. 可以先简化问题 考虑给出的n个字符串不存在包含关系. 那么 那么存在的情况 只可能有 两个字符串拼接起来能表示另外一个字符串 或者某个字符串的后缀可以 ...

  5. 1195: [HNOI2006]最短母串 - BZOJ

    Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串.Input 第一行是一个正整数n(n<=12), ...

  6. 【刷题】BZOJ 1195 [HNOI2006]最短母串

    Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12) ...

  7. BZOJ 1195 [HNOI2006]最短母串 (Trie图+状压+bfs最短路)

    BZOJ1195 LOJ10061 题目大意:给你$n$个模式串,求一个最短且字典序最小的文本串并输出这个串,$n<=12,len<=50$ 首先对所有模式串构造$Trie$图,$Trie ...

  8. bzoj 1195: [HNOI2006]最短母串【状压dp】

    我有病吧--明明直接枚举是否匹配就可以非要写hash,然后果然冲突了(--我个非酋居然还敢用hash 设f[s][i]为已选串状态为s并且最后一个串是i,还有预处理出g[i][j]表示最长有长为g[i ...

  9. BZOJ 1195: [HNOI2006]最短母串 AC自动机+状压+搜索

    思路比较直接. 由于 $n$ 很小,直接定义 $f[i][j]$ 表示当前在自动机中的节点 $i,$ 被覆盖串的集合为 $j$ 的方案数. #include <bits/stdc++.h> ...

随机推荐

  1. 浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理

    浅谈范德蒙德(Vandermonde)方阵的逆矩阵与拉格朗日(Lagrange)插值的关系以及快速傅里叶变换(FFT)中IDFT的原理 标签: 行列式 矩阵 线性代数 FFT 拉格朗日插值 只要稍微看 ...

  2. 洛谷 P5108 仰望半月的夜空 解题报告

    P5108 仰望半月的夜空 题目描述 半月的夜空中,寄托了多少人与人之间的思念啊 曦月知道,这些思念会汇集成一个字符串\(S(n = |S|)\) 由于思念汇集的过于复杂,因此曦月希望提炼出所有的思念 ...

  3. vi基础学习总结

    标签(空格分隔): vi 总结 vi是几乎所有类Unix/Linux系统下都默认装有的常用文本编辑工具.本文记录初学vi的一些小知识. 0.界面模式 在命令行使用"vi"编辑文档时 ...

  4. 洛谷P4198 楼房重建

    题意:给定序列,每次修改一个值,求前缀最大值的个数. 解:线段树经典应用. 每个节点维护最大值和该区间前缀最大值个数. 发现我们不用下传标记,只需要合并区间. 需要实现一个函数int ask([l r ...

  5. 【洛谷P1272】道路重建

    题目大意:给定一个 N 个节点的树,求至少剪掉多少条边才能使得从树中分离出一个大小为 M 的子树. 题解:考虑树形 dp,定义 \(dp[u][i][t]\) 为以 u 为根节点与前 i 个子节点构成 ...

  6. NB-IoT 的“前世今生”

    作者:个推B2D研发工程师 海晏 根据<爱立信2018移动报告>(Ericsson Mobility Report,June 2018)的预测,蜂窝物联网设备连接数将在2023年达到35亿 ...

  7. zabbix server安装(二)

    https://mp.weixin.qq.com/s/ogaqiX4vhtGLepuNf-1ItA zabbix依赖LNMP或LAMP,下面讲解LNMP安装到zabbix web页面的访问. 一.ng ...

  8. Flask-SQLAlchemy 无法创建Sqlite 数据库???

    <Flask web 开发>第五章数据库照书中的方法无法创建表,没有python的命令提示符,只是运行程序输入db.create_all()后文件夹里也没有data.sqlite文件 解决 ...

  9. 使用pandas导入csv文件到MySQL

    之前尝试过用命令行来解决csv文件导入到MySQL这个问题,没想到一直没有成功.之后会继续更新的吧,现在先用pandas来解决这个问题,虽然会复杂一点,但至少能用. 例子是导入movielens的ra ...

  10. webpack全局引入库

    我们在日常开发的时候会遇到一些每个页面都可能会引用到的库(例如jquery) 这可能会导致我们在每一个页面都需要写这样一个语句: import $ from 'jquery'; 可能有人会担心,最后打 ...