bzoj 1195
http://www.lydsy.com/JudgeOnline/problem.php?id=1195
状压DP。
首先去掉被包含的字符串。
对于字符串i和j,我们求出 当字符串j的左端点在字符串i的左端点的左边或与字符串i的左端点重合时,字符串i和字符串j可以重合的最长长度cost是多少。
就是求下面红色部分的最长长度cost:

这个强行枚举就可以了,反正数据这么小。
注意,因为我们已经去掉了被包含的字符串,所以不会出现下面这种情况:

所以去掉了被包含的字符串是为了保证当左端点单调时,右端点也是单调的。
建一个图,我们在图中i连到j一条费用为cost的有向边。
然后就是求不重复经过点,可以走的最长路径。
这是哈密顿路径问题,为NP问题,但是这道题数据范围很小,可以用状压DP。
对于输出字典序最小字符串那里,我们在找决策的时候比较一下即可。
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define fill(a,l,r,v) fill(a+l,a+r+1,v)
#define re(i,a,b) for(i=(a);i<=(b);i++)
#define red(i,a,b) for(i=(a);i>=(b);i--)
#define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define SF scanf
#define PF printf template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} const DB EPS=1e-;
inline int sgn(DB x){if(abs(x)<EPS)return ;return(x>)?:-;}
const DB Pi=acos(-1.0); inline int gint()
{
int res=;bool neg=;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return ;
if(z=='-'){neg=;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
return (neg)?-res:res;
}
inline LL gll()
{
LL res=;bool neg=;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return ;
if(z=='-'){neg=;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
return (neg)?-res:res;
} const int maxN=;
const int maxlen=; int N;
char s[maxN+][maxlen+]; int tempN;
char temps[maxN+][maxlen+];
int f[maxN+]; inline int smaller(char *s1,char *s2,int l1,int l2)
{
int i,len1=strlen(s1+),len2=strlen(s2+);
re(i,,min(len1-l1+,len2-l2+))if(s1[l1+i-]!=s2[l2+i-])return s1[l1+i-]<s2[l2+i-];
return len1-l1+<len2-l2+;
} inline int same(char *s1,char *s2,int l1,int l2,int len)
{
int i;
if(l1+len->strlen(s1+))return ;
if(l2+len->strlen(s2+))return ;
re(i,,len)if(s1[l1+i-]!=s2[l2+i-])return ;
return ;
} inline int check(char *s1,char *s2)
{
int i,l1=strlen(s1+),l2=strlen(s2+);
re(i,,l2-l1+)if(same(s1,s2,,i,l1))return ;
return ;
} int now,first[maxN+];
struct Tedge{int v,cost,next;}edge[maxN*maxN+];
inline void addedge(int u,int v,int cost){now++;edge[now].v=v;edge[now].cost=cost;edge[now].next=first[u];first[u]=now;} #define two(k) (1<<((k)-1))
#define wei(v,k) ((v>>(k-1))&1) int F[maxN+][(<<maxN)+],vis[maxN+][(<<maxN)+];
int head,tail;PII que[maxN*(<<maxN)+]; int cnt;char out[maxN*maxlen+]; int main()
{
/*freopen("substr.in","r",stdin);
freopen("substr.out","w",stdout);*/
int i,j;
N=gint();
re(i,,N)SF("%s\n",s[i]+);
re(i,,N)re(j,,N)if(i!=j)if(check(s[i],s[j])){f[i]=;break;}
mmcy(temps,s);
tempN=N;N=;
re(i,,tempN)if(!f[i])mmcy(s[++N],temps[i]);
if(N==)N=; now=-;mmst(first,-);
re(i,,N)re(j,,N)if(i!=j)
{
int leni=strlen(s[i]+),lenj=strlen(s[j]+),res=lenj;
while(res!= && !same(s[i],s[j],,lenj-res+,res))res--;
addedge(i,j,res);
} mmst(F,-);mmst(vis,);
head=;tail=-;
re(i,,N)F[i][two(i)]=,vis[i][two(i)]=,que[++tail]=PII(i,two(i));
while(head<=tail)
{
int u=que[head%(maxN*(<<maxN)+)].fi,state=que[head%(maxN*(<<maxN)+)].se,v,cost;head++;
vis[u][state]=;
for(i=first[u],v=edge[i].v,cost=edge[i].cost;i!=-;i=edge[i].next,v=edge[i].v,cost=edge[i].cost)
if(!wei(state,v) && F[u][state]+cost>F[v][state+two(v)])
{
F[v][state+two(v)]=F[u][state]+cost;
if(!vis[v][state+two(v)])
{
vis[v][state+two(v)]=;
que[(++tail)%(maxN*(<<maxN)+)]=PII(v,state+two(v));
}
}
} now=-;mmst(first,-);
re(i,,N)re(j,,N)if(i!=j)
{
int leni=strlen(s[i]+),lenj=strlen(s[j]+),res=lenj;
while(res!= && !same(s[i],s[j],,lenj-res+,res))res--;
addedge(j,i,res);
} int u=-,state=two(N+)-;
re(i,,N)if(u==- || F[u][state]<F[i][state] || (F[u][state]==F[i][state] && smaller(s[i],s[u],,)))u=i;
re(i,,strlen(s[u]+))out[++cnt]=s[u][i];
for(int T=N-;T;T--)
{
int p=-,o,v,cost;
for(i=first[u],v=edge[i].v,cost=edge[i].cost;i!=-;i=edge[i].next,v=edge[i].v,cost=edge[i].cost)
if(wei(state,v) && F[v][state-two(u)]+cost==F[u][state])
if(p==- || smaller(s[v],s[p],cost+,o))
p=v,o=cost+;
re(i,o,strlen(s[p]+))out[++cnt]=s[p][i];
state-=two(u);
u=p;
}
re(i,,cnt)putchar(out[i]);putchar('\n');
return ;
}
bzoj 1195的更多相关文章
- bzoj 1195: [HNOI2006]最短母串 爆搜
1195: [HNOI2006]最短母串 Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 894 Solved: 288[Submit][Status] ...
- BZOJ 1195: [HNOI2006]最短母串
1195: [HNOI2006]最短母串 Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 1346 Solved: 450[Submit][Status ...
- [BZOJ 1195] 最短母串
Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1195 Solution: 看到数据范围n<=12,就要往状压DP上想 为了保证后项 ...
- 【刷题】BZOJ 1195 [HNOI2006]最短母串
Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12) ...
- HNOI 2006 BZOJ 1195 最短母串
题面 问题描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字 ...
- bzoj 1195: [HNOI2006]最短母串【状压dp】
我有病吧--明明直接枚举是否匹配就可以非要写hash,然后果然冲突了(--我个非酋居然还敢用hash 设f[s][i]为已选串状态为s并且最后一个串是i,还有预处理出g[i][j]表示最长有长为g[i ...
- BZOJ 1195 [HNOI2006]最短母串 (Trie图+状压+bfs最短路)
BZOJ1195 LOJ10061 题目大意:给你$n$个模式串,求一个最短且字典序最小的文本串并输出这个串,$n<=12,len<=50$ 首先对所有模式串构造$Trie$图,$Trie ...
- BZOJ 1195: [HNOI2006]最短母串 AC自动机+状压+搜索
思路比较直接. 由于 $n$ 很小,直接定义 $f[i][j]$ 表示当前在自动机中的节点 $i,$ 被覆盖串的集合为 $j$ 的方案数. #include <bits/stdc++.h> ...
- 【33.28%】【BZOJ 1195】[HNOI2006]最短母串
Time Limit: 10 Sec Memory Limit: 32 MB Submit: 1208 Solved: 402 [Submit][Status][Discuss] Descript ...
随机推荐
- JS(四)
JS的属性好多,方法好多,一下子塞进来真的需要时间消化,很多东西都是当时记得很清楚,但忘得很快,看来需要经常去复习,主要是感觉后面一点的练习题好像少了点,所以就显得不是很熟练. 1.About Tim ...
- 博客换了,比较少用这个博客(http://loid.cf)
新博客地址: http://loid.cf/
- Java基础(十)内部类
1.使用内部类的原因(3点) ①内部类方法可以访问该内部类定义所在的作用域中的数据,包括私有数据. ②内部类可以对同一个包中的其他类隐藏起来. ③当想要定义一个回调函数且不想编写大量代码时,使用匿名内 ...
- JS中undefined与null的区别
1.概述: 在JavaScript中存在这样两种原始类型:Null与Undefined.这两种类型常常会使JavaScript的开发人员产生疑惑,在什么时候是Null,什么时候又是Undefined? ...
- Mina入门实例
继续上一篇,这篇主要讲通过mina往B端发送消息.并接受消息,mina是一个网络通信框架,封装了javaNIO.简单易用.网上有非常多关于他的介绍,在此不赘述了. 如上篇所介绍,完毕功能,须要五个类: ...
- 毕业设计 ASP.Net+EasyUI开发 X X露天矿调度管理信息系统(二)
这是本毕业设计的雏形和框架,实现的功能在左侧的功能框导航菜单内. 做的太烂,还是把学校名字给马赛克掉吧....省的挨校友批 登陆界面.. <cookie +ispostback实现记住我功能& ...
- HTML5 Canvas图片操作简单实例1
1.加载显示图片 <canvas id="canvasOne" class="myCanvas" width="500" height ...
- Hashtable键值集合
//Hashtable键值集合 键必须是维一的 类似于索引 Hashtable ht = new Hashtable(); ht.Add(, "中国"); ht.Add(, ); ...
- 东软实训2-在jsp中使用javaBean
在JSP中可以像使用普通类一样访问JavaBean,在脚本元素中实例化类的对象,调用对象的方法.JSP提供了3个动作元素,和来访问JavaBean. 1.1 动作用于初始化JavaBean,或者定位一 ...
- (原)python中matplotlib的颜色及线条控制
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6117528.html 参考网址: http://stackoverflow.com/questions ...