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 ...
随机推荐
- Hadoop2.4.1 64-Bit QJM HA and YARN HA + Zookeeper-3.4.6 + Hbase-0.98.8-hadoop2-bin HA Install
Hadoop2.4.1 64-Bit QJM HA and YARN HA Install + Zookeeper-3.4.6 + Hbase-0.98.8-hadoop2-bin HA(Hadoop ...
- 我为什么要再给lua写一个json模块
最近要给自己编写的服务器加上json解析模块.根据我当前的项目,可以预测服务器中使用json的地方: 通信.由于与客户端通信使用google protocolbuffer,仅在与SDK通信中使用jso ...
- Engineering Economics
相关简介 工程经济学 –-研究各种技术在使用过程中如何以最小的投入获得预期产出或者说如何以等量的投入获得最大的产出: –-如何用最低的寿命周期成本实现产品.作业以及服务的必要功能. 软件工程经济学 工 ...
- css hack 兼容性
做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我们会极不情愿的使用这个不太友好的方式来 达到大家要求的页面表现.我个人是不太推荐使用hack的,要知 ...
- 关于javax.crypto.BadPaddingException: Blocktype错误的几种解决方法
此文章转载自:http://www.myexception.cn/mobile/1259076.html 关于javax.crypto.BadPaddingException: Blocktype异常 ...
- Javascript:DOM表格操作
需求说明: /* *需求说明: *获取元素:tBodies,tHead,tFoot,rows,cells *表格的创建 *数据添加 *隔行变色 *删除操作,剩余表格重新计算,实现隔行变色 */ HTM ...
- sgu Flow construction
Flow construction 题目: 给出N个节点M条水管,要求在满足上下界的情况下.满足起点最小的流量. 算法: 这是最小流????不知道.仅仅知道用求解上下界最大流的方法就过了. 做这题收获 ...
- Transparency Tutorial with C# - Part 1
Download demo project - 4 Kb Download source - 6 Kb Download demo project - 5 Kb Download source - 6 ...
- CH BR8(小学生放假了-clock()/CLOCKS_PER_SEC-斜率优化常错集锦)
小学生放假了 总时限 26s 内存限制 256MB 出题人 zsyzzsoft 提交情况 16/150 初始分值 1500 锁定情况 背景 我们能见到的最可怕的事情,莫过于小学生放假了! 描述 小学生 ...
- angularjs之双向绑定
今天所学习的东西虽然不是很多 但是对我来说受益匪浅, 就比如说在table中要选中一行的话我们可以这样写: 模板中: <table ng-controller="tableContro ...