[BZOJ 1195] 最短母串
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] 最短母串的更多相关文章
- HNOI 2006 BZOJ 1195 最短母串
题面 问题描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字 ...
- 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 [HNOI2006]最短母串 bfs 状压 最短路 AC自动机
LINK:最短母串 求母串的问题.不适合SAM. 可以先简化问题 考虑给出的n个字符串不存在包含关系. 那么 那么存在的情况 只可能有 两个字符串拼接起来能表示另外一个字符串 或者某个字符串的后缀可以 ...
- 【状态压缩dp】1195: [HNOI2006]最短母串
一个清晰的思路就是状压dp:不过也有AC自动机+BFS的做法 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T ...
- [BZOJ1195]最短母串
1195: [HNOI2006]最短母串 Time Limit: 10 Sec Memory Limit: 32 MB Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最 ...
- 【loj10061】最短母串
#10061. 「一本通 2.4 练习 4」最短母串 内存限制:512 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: 1bentong 提交 提交 ...
- 2782: [HNOI2006]最短母串
2782: [HNOI2006]最短母串 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 3 Solved: 2[Submit][Status][Web ...
- BZOJ1195[HNOI2006]最短母串——AC自动机+BFS+状态压缩
题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字符串的 ...
随机推荐
- sqlplus 几个命令:
sqlplus 几个命令: 在sys,system,sysman,scott四个用户权限中,scott用户最低. 其权限依次从高到低. cmd进入sqlplus sqlplus 登录命令: 登录sys ...
- 封装安卓的okhttp
1.封装了get方法,handler更新主线程,回调的onsuccess,onfailure,onerror等方法 2.配置文件 api 'com.android.support:recyclervi ...
- git分支开发,分支(feature)同步主干(master)代码,以及最终分支合并到主干的操作流程
由于rebase执行速度慢,分支同步主干代码时,分支的每次提交都可能和主干产生冲突,需要解决的次数太多,影响提交效率. 同时,为了保证主干提交线干净(可以安全回溯),所以采用下面所说的merge法. ...
- 为什么VS没有提供平win64程序编写项
最近在学习C++和MFC编程,突然有个疑问,为什么每次新建项目时,都只有win32 console application,从来没见过win64的选项,于是去网上查了查,下面是我找到的几个答案: 作者 ...
- C# 文件类的操作---获取
如何获取指定目录包含的文件和子目录 . DirectoryInfo.GetFiles():获取目录中(不包含子目录)的文件,返回类型为FileInfo[],支持通配符查找: . DirectoryIn ...
- Java相关框架
框架 类型 设计(个人理解) HK2 自动注入框架 Jersey RESTful Jetty HTTP服务 Retrofit HTTP客户端 ActiveMQ 消息组件 主题.队列 Redis K-V ...
- JS 判断某变量是否为某数组中的一个值 的几种方法
1.正则表达式 js 中判断某个元素是否存在于某个 js 数组中,相当于 PHP 语言中的 in_array 函数. }; 用法如下: var arr=new Array([‘b’,2,‘a‘,4]) ...
- BZOJ 4522: [Cqoi2016]密钥破解
http://www.lydsy.com/JudgeOnline/problem.php?id=4522 题目:给你RSA密钥的公钥和密文,求私钥和原文,其中\(N=pq\le 2^{62}\),p和 ...
- springboot整合jsp模板
springboot整合jsp模板 在使用springboot框架里使用jsp的时候,页面模板使用jsp在pom.xnl中需要引入相关的依赖,否则在controller中无法返回到指定页面 〇.搭建s ...
- OpenCV-2.4.6-android-sdk 人脸识别demo搭建
最近项目需要研究下人脸识别,在领导推荐下准备研究OpenCV 一,上官网了解下 基本知识 http://docs.opencv.org/doc/tutorials/introduction/andro ...