最短母串 bzoj-1195 HNOI-2006

题目大意:给一个包含n个字符串的字符集,求一个字典序最小的字符串使得字符集中所有的串都是该串的子串。

注释:$1\le n\le 12$,$1\le max length \le 50$。

想法:刚开始在那里AC自动机半天,然后瞅了一眼数据范围... ...状压吧兄弟!!

首先,我们先做一些预处理:把可以被字符集中串包含的串都删掉;求出两个字符串连接后的长度(这个预处理暴力即可),设merge[i][j]表示串i和串j合并后的长度。

状态:dp[s][i]表示这个串已经包含了s状态的字符串且紧跟着的串是i的最短长度。

转移:dp[s][i]=min{dp[s^(1<<(j+1))][j]+merge[i][j]-length(j)};

最后,附上丑陋的代码... ...

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int mxn=61;
int n;
struct bind
{
char s[605];
int len;
bool operator < (const bind y) const
{
if(len!=y.len)return len<y.len;
for(int i=0;i<len;i++)
if(s[i]!=y.s[i])return s[i]<y.s[i];
return 0;
}
}f[1<<12][12],s[12];
int c[13][13];
bool ban[mxn]; bool ovl(int i,int j)
{
if(s[i].len<s[j].len)return 0;
char *p=strstr(s[i].s,s[j].s);
if(p==NULL)return 0;
return 1;
}
int clc(int x,int y)
{
bool flag=0;
for(int i=max(0,s[x].len-s[y].len);i<s[x].len;i++)
{
flag=1;
for(int j=i;j<s[x].len;j++)
if(s[x].s[j]!=s[y].s[j-i]){flag=0;break;}
if(flag)return s[x].len-i;
}
return 0;
}
bind merge(int S,int u,int v)
{
bind tmp=f[S][u];
strcat(tmp.s,s[v].s+c[u][v]);
tmp.len=f[S][u].len-c[u][v]+s[v].len;
return tmp;
}
void Dp()
{
int i,j,ed=(1<<n)-1;
for(i=0;i<=ed;i++)
for(j=0;j<n;j++)f[i][j].len=INF;
for(i=0;i<n;i++)f[1<<i][i]=s[i];
for(i=1;i<=ed;i++)
{
for(j=0;j<n;j++)
{
if((i>>j)&1)
for(int k=0;k<n;k++)
{
if((i>>k)&1) continue;
bind tmp=merge(i,j,k);
if(tmp<f[i|(1<<k)][k])f[i|(1<<k)][k]=tmp;
}
}
}
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%s",s[i].s),s[i].len=strlen(s[i].s);
for(int i=0;i<n;i++)
for(j=0;j<n;j++)
if(i!=j && ovl(i,j) && !ban[i])ban[j]=1;
int cnt=0;
for(int i=0;i<n;i++)if(!ban[i])s[cnt++]=s[i];
n=cnt;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i!=j)c[i][j]=clc(i,j);
Dp();
int ans=0,ed=(1<<n)-1;
for(int i=1;i<n;i++)
if(f[ed][i]<f[ed][ans])ans=i;
printf("%s",f[ed][ans].s);
return 0;
}

小结:看到了数据做题是一种解题想法,但是考试的时候看数据范围猜复杂度我tm就没成功过... ...

[bzoj1195][HNOI2006]最短母串_动态规划_状压dp的更多相关文章

  1. [HNOI2006]最短母串问题——AC自动机+状压+bfs环形处理

    Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 32MB Input 第一行是一个正整数n(n< ...

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

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

  3. Bzoj1195 [HNOI2006]最短母串 [状态压缩]

    Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1304  Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...

  4. BZOJ1195 [HNOI2006]最短母串 【状压dp】

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

  5. Bzoj1195 [HNOI2006]最短母串 [AC自动机]

    Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1304  Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...

  6. BZOJ1195 [HNOI2006]最短母串 AC自动机 bfs

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 传送门 - BZOJ1195 题意概括 给出一堆串,然后求一个包含这些串的所有串的最短的中的字典序最小的. 题解 先造一个AC ...

  7. BZOJ1195 HNOI2006最短母串(状压dp)

    按照子串出现的先后考虑.令f[i][j]为已经出现的字符串集合为i,最后一个出现的字符串为j时的最短串长,预处理一下任意两个串的最长重叠长度,转移显然.有点麻烦的是字典序,强行增加代码难度. 另一个比 ...

  8. [BZOJ1195]:[HNOI2006]最短母串(AC自动机+BFS)

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

  9. BZOJ1195: [HNOI2006]最短母串(Trie图,搜索)

    Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12) ...

随机推荐

  1. [整理] C#调用SQLDMO.DLL时间数据库备份 / 还原。 (香神无涯) // C#实现SQLSERVER2000数据库备份还原的两种方法 (带进度条)

    /// <summary>/// 通过调用MSSQL的SQLDMO.DLL文件来实现备份数据库/// 1.首先在在项目中引用SQLDMO.DLL文件./// 2.在引用中的SQLDMO.D ...

  2. 0605-类的继承、重写、parent、final

    定义一个子类(man) //定义一个类 class renlei{ var $name = '王五'; var $age = ''; var $sex = ''; var $todo = ''; fu ...

  3. go之switch

    switch 条件语句一 格式 switch initialization{ case v1: // do something case v2: // do something case v2: // ...

  4. Oracle 当输入参数允许为空时

    场景: 有一个存储过程p_test 带有多个输入参数code.name.number p_test(code IN VARCHAR2,nameIN VARCHAR2,number IN VARCHAR ...

  5. Vue2-Editor 使用

    Vue-Editor底层采取的是quill.js,而quill.js采用的是html5的新属性classList,所以版本低于ie10会报错“无法获取未定义或 null 引用的属性‘confirm’” ...

  6. SAP computer之RAM

    RAM The RAM is a 16 X 8 static TTL RAM. We can program the RAM by means of the address and data swit ...

  7. Eclipse之调试代码和返回

    编写代码时,经常会遇到各种莫名其妙的问题,为了检测程序是哪里出现问题,我们通过断点调试来判断哪一步出错 一.断点 在需要断点的地方,在左侧双击鼠标设置断点,可设置多个 去掉断点:在断点上双击一下,没有 ...

  8. java Web(4)

    Web 应用程序状态管理 通过隐藏表单域 hidden,cookie,session,重写URL来实现: cookie存在于客户端,浏览器关闭时失效 cookie原理:服务器在响应请求时将一些数据以“ ...

  9. CXF-JAX-WS开发(一)入门案例

    一.Web Service 1.定义 W3C定义,Web服务(Web service)应当是一个软件系统,用以支持网络间不同机器的互动操作. 2.作用 多系统间数据通信 二.CXF是什么? CXF是目 ...

  10. Dispatch Queues and Thread Safety

    Dispatch Queues and Thread Safety It might seem odd to talk about thread safety in the context of di ...