BZOJ1195 HNOI2006最短母串(状压dp)
按照子串出现的先后考虑。令f[i][j]为已经出现的字符串集合为i,最后一个出现的字符串为j时的最短串长,预处理一下任意两个串的最长重叠长度,转移显然。有点麻烦的是字典序,强行增加代码难度。
另一个比较简单的做法是上AC自动机,建出来后类似地令f[i][j]为已经出现的字符串集合为i,在自动机上点j时的最短串长,相当于跑一个最短路,bfs时每次优先选字典序最小的边即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 12
#define M 52
int n,len[N],d[N][N];
char s[N][M];
struct str
{
int n;char s[N*M];
bool operator <(const str&a) const
{
for (int i=;i<=n;i++)
if (s[i]!=a.s[i]) return s[i]<a.s[i];
return ;
}
};
str get(int p,int q);
struct data
{
int i,j,x,n,s[N+];
bool operator <(const data&a) const
{
if (x!=a.x) return x<a.x;
return get(i,j)<get(a.i,a.j);
}
}f[<<N][N];
str get(int p,int q)
{
int n=f[p][q].n;
str v;memset(v.s,,sizeof(v.s));
int x=len[f[p][q].s[]];
for (int i=;i<=len[f[p][q].s[]];i++) v.s[i]=s[f[p][q].s[]][i];
for (int i=;i<=n;i++)
for (int j=d[f[p][q].s[i-]][f[p][q].s[i]]+;j<=len[f[p][q].s[i]];j++)
v.s[++x]=s[f[p][q].s[i]][j];
v.n=x;
return v;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj1195.in","r",stdin);
freopen("bzoj1195.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=;i<n;i++) scanf("%s",s[i]+),len[i]=strlen(s[i]+);
for (int i=;i<n;i++)
for (int j=;j<n;j++)
if (i!=j)
for (int k=;k<=len[i];k++)
{
bool flag=;
for (int x=;x<=len[j]&&k+x-<=len[i];x++)
if (s[i][k+x-]!=s[j][x]) {flag=;break;}
if (flag) {d[i][j]=min(len[i]-k+,len[j]);break;}
}
for (int i=;i<(<<n);i++)
for (int j=;j<n;j++)
f[i][j].x=,f[i][j].i=i,f[i][j].j=j;
for (int i=;i<n;i++) f[<<i][i].x=len[i],f[<<i][i].s[]=i,f[<<i][i].n=;
for (int i=;i<(<<n);i++)
for (int j=;j<n;j++)
if (i&(<<j))
for (int k=;k<n;k++)
if (!(i&(<<k)))
if (d[j][k]==len[k]) f[i|(<<k)][j]=min(f[i|(<<k)][j],f[i][j]),f[i|(<<k)][j].i=i|(<<k);
else
{
data t=f[i][j];
f[i][j].x+=len[k]-d[j][k];
f[i][j].s[++f[i][j].n]=k;
f[i|(<<k)][k]=min(f[i|(<<k)][k],f[i][j]),f[i|(<<k)][k].i=i|(<<k),f[i|(<<k)][k].j=k;
f[i][j]=t;
}
for (int i=;i<n;i++) f[(<<n)-][]=min(f[(<<n)-][],f[(<<n)-][i]),f[(<<n)-][].j=;
printf("%s",get((<<n)-,).s+);
return ;
}
BZOJ1195 HNOI2006最短母串(状压dp)的更多相关文章
- [bzoj1195][HNOI2006]最短母串_动态规划_状压dp
最短母串 bzoj-1195 HNOI-2006 题目大意:给一个包含n个字符串的字符集,求一个字典序最小的字符串使得字符集中所有的串都是该串的子串. 注释:$1\le n\le 12$,$1\le ...
- BZOJ1195 [HNOI2006]最短母串 【状压dp】
题目 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入格式 第一行是一个正整数n(n<=12),表示给定的字符串的 ...
- Bzoj1195 [HNOI2006]最短母串 [状态压缩]
Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 1304 Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...
- [bzoj1195] [hnoi2006] 最短母串
本题是一个经典的状压dp问题,在紫书中有着加强版的例题. 本题的难度主要体现在:如何输出字符串字典序最小. 为了解决这个问题,我们有两种常用方案: 1) 我们可以采用bfs输出路径的方法,使用+1来输 ...
- BZOJ1195[HNOI2006]最短母串——AC自动机+BFS+状态压缩
题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字符串的 ...
- Bzoj1195 [HNOI2006]最短母串 [AC自动机]
Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 1304 Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...
- bzoj1195 [HNOI2006]最短母串 AC 自动机+状压+bfs
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1195 题解 建立 AC 自动机,然后构建出 trie 图. 然后直接在 trie 图上走.但是 ...
- BZOJ1195 [HNOI2006]最短母串 AC自动机 bfs
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 传送门 - BZOJ1195 题意概括 给出一堆串,然后求一个包含这些串的所有串的最短的中的字典序最小的. 题解 先造一个AC ...
- [BZOJ1195]:[HNOI2006]最短母串(AC自动机+BFS)
题目传送门 题目描述 给定n个字符串(S1,S2,…,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,…,Sn)都是T的子串. 输入格式 第一行是一个正整数n,表示给定的字符串的个数 ...
随机推荐
- 通过c#操作word文档的其他方式
如果不嫌麻烦可以选择MS的word组件,因为过于庞大复杂.一般都是在无法满足要求的情况下才采用此种方式 参考链接:http://blog.csdn.net/lu930124/article/detai ...
- 深圳Uber优步司机奖励政策(1月4日~1月10日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 问题:MongoDB C# driver异常:Truncation resulted in data loss
问题描述: 原因分析: MongoDB C#驱动在读取数据记录遇到数值类型字段时,如果没有设置允许截断,将抛出TruncationException. 解决方法: [BsonRepresentatio ...
- H5-基础-day01
类选择器和ID选择器 相同点:可以应用于任何元素不同点: 1.ID选择器只能在文档中使用一次.与类选择器不同,在一个HTML文档中,ID选择器只能使用一次,而且仅一次.而类选择器可以使用多次. 2 ...
- windows安装logstash-input-jdbc并使用其导入MMSQL数据
1.安装logstash 2.修改logstash 文件夹下Gemfile文件 将source改为:https://gems.ruby-china.org 3.进入bin目录 执行logstash-p ...
- Selenium(Python) ddt读取CSV文件数据驱动
import csvimport unittestfrom time import sleep from ddt import ddt, data, unpackfrom selenium impor ...
- 错误码:2003 不能连接到 MySQL 服务器在 (10061)
今天在ubuntu上安装了mysql服务器,在windows上用客户端软件连接mysql服务器时,出现错误: 错误码: 不能连接到 MySQL 服务器在 () 折腾来折腾去没搞好,防火墙也关了,330 ...
- jQuery用unbind方法去掉hover事件及其他方法介绍
近日项目开发十分的繁忙,其中一个需求是实现响应式导航.(响应式的问题我们在css相关的博客中再交流) 大家都知道导航是需要下来菜单效果的,必然就会用到 jQuery的 hover() 方法.若是导航放 ...
- springMVC怎么改变form的提交方式为put或者delete
想着练习一下创建restful风格的网站呢,结果发现在jsp页面上并不能灵活使用put和delete提交方式.下面我的解决办法 一. form 只支持post和get两种提交方式,只支持get提交方式 ...
- canvas学习(一):线条,图像变换和状态保存
canvas学习(一):线条,图像变换和状态保存 一:绘制一条线段: var canvas = document.getElementById('canvas') var ctx = canvas.g ...