首先kmp求出每个子串能放在哪些位置。接下来的两部分贪心和状压都可以,各取比较方便的。

  最大值考虑贪心。考虑枚举子串的左端点出现顺序,在此基础上每个子串的位置肯定都应该尽量靠前,有是否与上个子串有交两种选择,如果有交一定会使交集最小,于是枚举第一个子串出现位置并暴力枚举4!*23种情况。

  最小值考虑状压。首先把被包含的子串去掉方便处理。将线段排序,设f[i][S]为当前覆盖到的最右位置为i已出现的子串集合为S时的最小覆盖长度,转移时考虑上条线段是否与其有交,单调队列优化转移(因为懒写了线段树)。虽然非常麻烦但可能还是比贪心好点的。而最大值由于不能删掉被包含子串状压简直没法做。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 10010
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int T,n,m,nxt[N],cnt[],mn[N*][<<],f[N*][<<],tree[<<][N<<],ans;
bool flag[];
char s[N],a[][N];
struct data
{
int x,y,op;
bool operator <(const data&a) const
{
return x<a.x;
}
}b[][N],c[*N];
void dfs(int k,int last,int r,int s)
{
if (k==m) {ans=max(ans,s);return;}
for (int i=;i<=m;i++)
if (!flag[i])
{
int u=,v=;
for (int j=;j<=cnt[i];j++)
if (b[i][j].x>=last)
if (b[i][j].x<=r) u=j;
else {v=j;break;}
flag[i]=;
if (u) dfs(k+,b[i][u].x,max(r,b[i][u].y),s+max(b[i][u].y-r,));
if (v) dfs(k+,b[i][v].x,max(r,b[i][v].y),s+b[i][v].y-b[i][v].x+);
flag[i]=;
}
}
void rebuild()
{
bool flag[]={};
for (int i=;i<=m;i++)
for (int j=;j<=m;j++)
if (i!=j&&(strlen(a[i]+)<strlen(a[j]+)||(strlen(a[i]+)==strlen(a[j]+)&&i>j)))
{
for (int k=;k<=cnt[i];k++)
if (b[i][k].x>=b[j][].x&&b[i][k].y<=b[j][].y) {flag[i]=;break;}
}
n=;int m2=;
for (int i=;i<=m;i++)
if (!flag[i])
{
for (int j=;j<=cnt[i];j++)
c[++n]=b[i][j],c[n].op=m2;
m2++;
}
m=m2;
sort(c+,c+n+);
}
void ins(int op,int k,int l,int r,int p,int x)
{
tree[op][k]=min(tree[op][k],x);
if (l==r) return;
int mid=l+r>>;
if (p<=mid) ins(op,k<<,l,mid,p,x);
else ins(op,k<<|,mid+,r,p,x);
}
int query(int op,int k,int l,int r,int x,int y)
{
if (x>y) return N;
if (l==x&&r==y) return tree[op][k];
int mid=l+r>>;
if (y<=mid) return query(op,k<<,l,mid,x,y);
else if (x>mid) return query(op,k<<|,mid+,r,x,y);
else return min(query(op,k<<,l,mid,x,mid),query(op,k<<|,mid+,r,mid+,y));
}
void work()
{
memset(f,,sizeof(f));f[][]=;
memset(mn,,sizeof(mn));mn[][]=;
memset(tree,,sizeof(tree));
int t=;
for (int i=;i<=n;i++)
{
while (c[t+].y<c[i].x) t++;
for (int j=;j<(<<m);j++)
if (j&(<<c[i].op)) f[i][j]=min(mn[t][j^(<<c[i].op)]+c[i].y-c[i].x+,query(j^(<<c[i].op),,,n,t+,i-)+c[i].y);
for (int j=;j<(<<m);j++)
mn[i][j]=min(mn[i-][j],f[i][j]),ins(j,,,n,i,f[i][j]-c[i].y);
}
ans=mn[n][(<<m)-];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4560.in","r",stdin);
freopen("bzoj4560.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
T=read();
while (T--)
{
scanf("%s",s+);n=strlen(s+);
m=read();
for (int i=;i<=m;i++) scanf("%s",a[i]+);
memset(cnt,,sizeof(cnt));
for (int i=;i<=m;i++)
{
nxt[]=-;int t=strlen(a[i]+);
for (int k=;k<=t;k++)
{
int j=nxt[k-];
while (~j&&a[i][j+]!=a[i][k]) j=nxt[j];
nxt[k]=j+;
}
int x=;
for (int k=;k<=n;k++)
{
while (~x&&a[i][x+]!=s[k]) x=nxt[x];
x++;if (x==t) cnt[i]++,b[i][cnt[i]].x=k-t+,b[i][cnt[i]].y=k,x=nxt[x];
}
}
for (int i=;i<=m;i++) sort(b[i]+,b[i]+cnt[i]+);
ans=;dfs(,,,);int tmp=ans;
rebuild();work();
cout<<ans<<' '<<max(ans,tmp)<<endl;
}
return ;
}

BZOJ4560 JLOI2016字符串覆盖(kmp+贪心+状压dp+单调队列)的更多相关文章

  1. 【BZOJ4560】[JLoi2016]字符串覆盖 KMP+状压DP

    [BZOJ4560][JLoi2016]字符串覆盖 Description 字符串A有N个子串B1,B2,…,Bn.如果将这n个子串分别放在恰好一个它在A中出现的位置上(子串之间可以重叠)这样A中的若 ...

  2. POJ 1795 DNA Laboratory (贪心+状压DP)

    题意:给定 n 个 字符串,让你构造出一个最短,字典序最小的字符串,包括这 n 个字符串. 析:首先使用状压DP,是很容易看出来的,dp[s][i] 表示已经满足 s 集合的字符串以 第 i 个字符串 ...

  3. bzoj3717 [PA2014]Pakowanie 贪心+状压DP

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3717 题解 这道题大概也就只能算常规的状压 DP 吧,但是这个状态和转移的设计还是不是很好想. ...

  4. [BZOJ4560][JLOI2016]字符串覆盖(贪心+DP)

    先用KMP求出所有可以放的位置,然后两个值分别处理. 最大值: 贪心,4!枚举放的先后位置顺序,2^3枚举相邻两个串是否有交. 若有交,则后一个的起始位置一定是离前一个的结束位置最近的位置,无交也一样 ...

  5. BZOJ4560 [JLoi2016]字符串覆盖

    题意 字符串A有N个子串B1,B2,-,Bn.如果将这n个子串分别放在恰好一个它在A中出现的位置上(子串之间可以重叠) 这样A中的若干字符就被这N个子串覆盖了.问A中能被覆盖字符个数的最小值和最大值. ...

  6. CodeForces165E 位运算 贪心 + 状压dp

    http://codeforces.com/problemset/problem/165/E 题意 两个整数 x 和 y 是 兼容的,如果它们的位运算 "AND" 结果等于 0,亦 ...

  7. BZOJ4416 [Shoi2013]阶乘字符串 【序列自动机 + 状压dp】

    题目链接 BZOJ4416 题解 建立序列自动机,即预处理数组\(nxt[i][j]\)表示\(i\)位置之后下一个\(j\)出现的位置 设\(f[i]\)表示合法字符集合为\(i\)的最短前缀,枚举 ...

  8. 2018.08.29 NOIP模拟 movie(状压dp/随机化贪心)

    [描述] 小石头喜欢看电影,选择有 N 部电影可供选择,每一部电影会在一天的不同时段播 放.他希望连续看 L 分钟的电影.因为电影院是他家开的,所以他可以在一部电影播放过程中任何时间进入或退出,当然他 ...

  9. Codeforces 429C Guess the Tree(状压DP+贪心)

    吐槽:这道题真心坑...做了一整天,我太蒻了... 题意 构造一棵 $ n $ 个节点的树,要求满足以下条件: 每个非叶子节点至少包含2个儿子: 以节点 $ i $ 为根的子树中必须包含 $ c_i ...

随机推荐

  1. 使用Python操作Office——EXCEL

    首先介绍下office win32 com接口,这个是MS为自动化提供的操作接口,比如我们打开一个EXCEL文档,就可以在里面编辑VB脚本,实现我们自己的效果.对于这种一本万利的买卖,Python怎么 ...

  2. [Git add . ] 遇到The file will have its original line endings in your working directory 解决办法

    1.在新项目中使用[ git add . ]时出现: warning: LF will be replaced by CRLF in ...... The file will have its ori ...

  3. Delphi 过程类型

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  4. 渗透测试实验(i春秋 真的很简单)

    首先利用给的提示: 所以用户名是 ichunqiu 密码是adab29e084ff095ce3eb 可以确定一般密码都是md5的,但是这个20位 应该去掉ada b29e084ff095ce3e才是正 ...

  5. 博科brocade光纤交换机alias-zone的划分-->实操案例

    一,图形化操作 光纤交换机作为SAN网络的重要组成部分,在日常应用中非常普遍,本次将以常用的博科交换机介绍基本的配置方法. 博科300实物图: 环境描述: 如上图,四台服务器通过各自的双HBA卡连接至 ...

  6. [bzoj1359][Baltic2009]Candy

    给定N个数对$(T_i,S_i)$,表示时刻$S_i$时在位置$T_i$处出现一粒糖果.有一些机器人可供使用,每个机器人可花费一单位时间向相邻位置移动.要求用最少的机器人接到全部糖果.时刻0时机器人位 ...

  7. 炒鸡简单的javaScript的call和apply方法

    解释一 作者:杨志 链接:https://www.zhihu.com/question/20289071/answer/14644278 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商 ...

  8. Linux使用imagemagick的convert命令压缩图片,节省服务器空间

    1,安装imagemagick yum install ImageMagick 2,获取图片 find ./ -regex '.*\(jpg\|JPG\|png\|jpeg\)' -size +500 ...

  9. .NET基础知识之七——索引器

           索引器是什么?有什么作用?索引器允许类的实例以访问数组的形式来访问对象里面的属性.如我们经常可以看到类似于dr["name"]="test",或者 ...

  10. jdk带的一些工具,强悍

    这些工具有的已经接触到了,功能很强悍,但是使用也有点复杂(参数) 在代码中使用System.setProperty()或者在启动程序时使用-D选项设置代理服务器地址和端口 看看别人的研究: JDK自带 ...