Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1195

Solution:

看到数据范围n<=12,就要往状压DP上想

为了保证后项无关性,首先肯定要先将已被包含的子串去除,这样保证两个串合并时必然是首尾相接

接下来预处理出第i个串接在第j个串后需要的长度,暴力即可

记录最后一个串,设 dp[s][i] 为选择的集合为 s,最后一个串是 i 的最小长度,枚举前一个串进行转移即可

此题要求保证字典序最小,因此要同时记录 dp[s][i] 的字符串

时间复杂度:上界为O(N^2 · 2^N * 600),但明显达不到这个上界,当n=12 时应为 4e7 左右

空间复杂度:此题空间卡得很紧,最好将int换为short

Code:

#include <bits/stdc++.h>

using namespace std;
const int INF=; struct sub
{
short len;
char s[];
void read(){scanf("%s",s);len=strlen(s);}
bool operator < (const sub &t) const //重载小于号方便使用min
{
if (len!=t.len) return len<t.len;
for(int i=;i<len;i++)
if(s[i]!=t.s[i]) return s[i]<t.s[i];
return true;
}
}dp[][],dat[],res; short n,ban[],pre[][],cnt=; bool ide(int l,int posl,int r)
{
for(int posr=;posr<dat[r].len && posl<dat[l].len;posr++,posl++)
if(dat[l].s[posl]!=dat[r].s[posr]) return false;
return true;
} bool overlap(int l,int r)
{
if(dat[l].len<dat[r].len) return false;
for(int i=;i<=dat[l].len-dat[r].len;i++)
if(ide(l,i,r)) return true;
return false;
} int cal(int l,int r)
{
for(int i=max(,dat[l].len-dat[r].len);i<dat[l].len;i++)
if(ide(l,i,r)) return dat[r].len-(dat[l].len-i);
return dat[r].len;
} sub new_node(int S,int u,int v)
{
sub ret=dp[S][u];
for(int i=dat[v].len-pre[u][v];i<dat[v].len;i++)
ret.s[ret.len++]=dat[v].s[i];
return ret;
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) dat[i].read(); for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(overlap(i,j) && i!=j && (!overlap(j,i) || i>j)) ban[j]=true; //对二者相同的特判 for(int i=;i<=n;i++)
if(!ban[i]) dat[++cnt]=dat[i]; for(int i=;i<=cnt;i++)
for(int j=;j<=cnt;j++)
if(i!=j) pre[i][j]=cal(i,j); //预处理出j接在i后需要多长 for(int i=;i<(<<n);i++) for(int j=;j<=n;j++) dp[i][j].len=INF;
for(int i=;i<=cnt;i++) dp[<<(i-)][i]=dat[i]; for(int i=;i<(<<cnt);i++)
for(int j=;j<=cnt;j++) if(i&(<<(j-)))
for(int k=;k<=cnt;k++) if(!(i&(<<(k-))))
dp[i|(<<(k-))][k]=min(dp[i|(<<(k-))][k],new_node(i,j,k)); res.len=INF;
for(int i=;i<=cnt;i++)
res=min(res,dp[(<<cnt)-][i]);
printf("%s\n",res.s); return ;
}

Review:

1、根据特殊数据范围   ----->   推测算法

2、非全局变量的初始化:

char数组在函数内部是乱码,要用memset(char,'\0',sizeof(char))才能清零

如在函数内新定义的一定要初始化

3、在需要多次对结构体进行比较时,不妨使用重载运算符+min/max的方式

4、如空间卡得很死,将int--->short,long long ---> long

5、要保持字典序最小,最朴素的方式就是将字符串存储下来

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

  1. HNOI 2006 BZOJ 1195 最短母串

    题面 问题描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字 ...

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

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

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

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

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

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

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

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

  6. [BZOJ1195]最短母串

    1195: [HNOI2006]最短母串 Time Limit: 10 Sec  Memory Limit: 32 MB Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最 ...

  7. 【loj10061】最短母串

    #10061. 「一本通 2.4 练习 4」最短母串 内存限制:512 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: 1bentong 提交    提交 ...

  8. 2782: [HNOI2006]最短母串

    2782: [HNOI2006]最短母串 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 3  Solved: 2[Submit][Status][Web ...

  9. BZOJ1195[HNOI2006]最短母串——AC自动机+BFS+状态压缩

    题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字符串的 ...

随机推荐

  1. 【BZOJ】2453: 维护队列【BZOJ】2120: 数颜色 二分+分块(暴力能A)

    先说正解:把所有相同的数相成一个链在每一个区间里的种数就是不同链的链头,那么记录每个数的上个相同数所在位置,那么只要找出l到r之间前驱值在l之前的数的个数就可以了 本人打的暴力,有一个小技巧,用cha ...

  2. 自己模拟实现一下Google的赛马Doodle

    今天的Google Doodle是个动态的,是一个骑马的动态Doodle,是谷歌纪念英国实验摄影师埃德沃德·迈布里奇182周年诞辰,埃德沃德·迈布里奇是运动摄影的开创者,所以谷歌涂鸦以一个运动的摄影作 ...

  3. 从零开始学习MXnet(四)计算图和粗细粒度以及自动求导

    这篇其实跟使用MXnet的关系不大,但对于我们理解深度学习的框架设计还是很有帮助的. 首先还是对promgramming models的一个简单介绍,这个东西实际上是在编译里面经常出现的东西,我们在编 ...

  4. last_query_cost

    The total cost of the last compiled query as computed by the query optimizer. This is useful for com ...

  5. Java并发(4)- synchronized与CAS

    引言 上一篇文章中我们说过,volatile通过lock指令保证了可见性.有序性以及"部分"原子性.但在大部分并发问题中,都需要保证操作的原子性,volatile并不具有该功能,这 ...

  6. PCIe 中的Capability 结构的寻址

    PCI-X 和PCIe 总线规范要求其设备必须支持Capabilities 结构.在PCI 总线的基本配置空间中,包含一个Capabilities Pointer 寄存器,该寄存器存放Capabili ...

  7. bzoj3382 [Usaco2004 Open]Cave Cows 3 洞穴里的牛之三

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3382 [题解] 套路题. 首先我们会发现曼哈顿距离不好处理,难道要写kdtree??? (k ...

  8. [BZOJ3238][Ahoi2013]差异解题报告|后缀数组

    Description 先分析一下题目,我们显然可以直接算出sigma(len[Ti]+len[Tj])的值=(n-1)*n*(n+1)/2 接着就要去算这个字符串中所有后缀的两两最长公共前缀总和 首 ...

  9. 联系人数据存储Demo源代码

    源码下载地址:07-联系人数据存储.zip35.8 KB // MJPerson.h // //  MJPerson.h //  07-联系人数据存储 // //  Created by apple ...

  10. [bzoj2038][2009国家集训队]小Z的袜子(hose)——莫队算法

    Brief Description 给定一个序列,您需要处理m个询问,每个询问形如[l,r],您需要回答在区间[l,r]中任意选取两个数相同的概率. Algorithm Design 莫队算法入门题目 ...