题目大意:

用集合A中的串构造出一个串,使之让很多其它的setB中的串成为他的子串。

思路分析:

Codeforces 86C 几乎相同。

只是这里是要用A中的构造。

先用A 和 B的串构造一个自己主动机。然后对于A集合的尾结点给出一个最大后缀匹配,对于B集合的尾结点给一个权值。

dp[i][j][k] 表示已经构造出来了一个长度为i的串,如今走到了自己主动机的j结点。i长度后面有k个字符是没有匹配到的。

继续在自己主动机上走进行状态转移。

if(isword >= k +1 )dp [i+1] [j->next[d] ][0] = max(dp [i+1] [ j->next[d] ][0] , dp[i][j][k] + j->next[d]->val)...

else if( k+1 <= 10) dp [i+1] [j->next[d] ] [k+1 ] = max (dp[i+1][ j->next[d] ] [k+1] , dp [i][j][k] + j->next[d]->val)

...

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <utility>
#include <string>
#include <vector>
#define inf 0x3f3f3f3f
using namespace std;
const int mod = 1000000009;
const char tab = 'a';
const int max_next = 26;
int rev[256];
struct trie
{
struct trie *fail;
struct trie *next[max_next];
int isword,tip;
int index;
};
struct AC
{
trie *que[100005],*root,ac[100005];
int head,tail;
int idx;
trie *New()
{
trie *temp=&ac[idx];
for(int i=0;i<max_next;i++)temp->next[i]=NULL;
temp->fail=NULL;
temp->isword=0;
temp->index=idx++;
temp->tip=0;
return temp;
}
void init()
{
idx=0;
root=New();
}
void Insert(trie *root,char *word,int len,int cmd){
trie *t=root;
for(int i=0;i<len;i++){
if(t->next[word[i]-tab]==NULL)
t->next[word[i]-tab]=New();
t=t->next[word[i]-tab];
}
if(cmd)t->isword=len;
else t->tip++;
}
void acbuild(trie *root){
int head=0,tail=0;
que[tail++]=root;
root->fail=NULL;
while(head<tail){
trie *temp=que[head++],*p;
for(int i=0;i<max_next;i++){
if(temp->next[i]){
if(temp==root)temp->next[i]->fail=root;
else {
p=temp->fail;
while(p!=NULL){
if(p->next[i]){
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL)temp->next[i]->fail=root;
}
//if(temp->next[i]->fail->isword)
temp->next[i]->isword=max(temp->next[i]->isword,temp->next[i]->fail->isword);
temp->next[i]->tip+=temp->next[i]->fail->tip;
que[tail++]=temp->next[i];
}
else if(temp==root)temp->next[i]=root;
else temp->next[i]=temp->fail->next[i];
}
}
}
void tra()
{
for(int i=0;i<idx;i++)
{
if(ac[i].fail!=NULL)printf("fail = %d ",ac[i].fail->index);
for(int k=0;k<max_next;k++)
printf("%d ",ac[i].next[k]->index);
puts("");
}
}
}sa;
char word[55];
int dp[65][1005][11]; int solve(int L)
{
memset(dp,-1,sizeof dp);
dp[0][0][0]=0;
for(int i=0;i<L;i++)
{
for(int j=0;j<sa.idx;j++)
{
for(int k=0;k<10;k++)
{
if(dp[i][j][k]<0)continue;
for(int d=0;d<4;d++)
{
if(sa.ac[j].next[d]->isword>=k+1)
dp[i+1][sa.ac[j].next[d]->index][0]=max(dp[i+1][sa.ac[j].next[d]->index][0],dp[i][j][k]+sa.ac[j].next[d]->tip);
else if(k+1<=10)
dp[i+1][sa.ac[j].next[d]->index][k+1]=max(dp[i+1][sa.ac[j].next[d]->index][k+1],dp[i][j][k]+sa.ac[j].next[d]->tip);
}
}
}
}
int ans=0;
for(int l=1;l<=L;l++)
for(int i=0;i<sa.idx;i++)
ans=max(ans,dp[l][i][0]);
return ans;
} int main()
{
rev['A']=0;
rev['C']=1;
rev['G']=2;
rev['T']=3;
int m,L,n;
while(cin>>m>>n>>L)
{
sa.init();
for(int i=1;i<=m;i++)
{
cin>>word;
sa.Insert(sa.root,word,strlen(word),1);
}
for(int i=1;i<=n;i++)
{
cin>>word;
sa.Insert(sa.root,word,strlen(word),0);
}
sa.acbuild(sa.root);
printf("%d\n",solve(L));
}
return 0;
}

Zoj 3535 Gao the String II (AC自己主动机+dp)的更多相关文章

  1. ZOJ 3228 Searching the String (AC自己主动机)

    题目链接:Searching the String 解析:给一个长串.给n个不同种类的短串.问分别在能重叠下或者不能重叠下短串在长串中出现的次数. 能重叠的已经是最简单的AC自己主动机模板题了. 不能 ...

  2. zoj 3430 Detect the Virus(AC自己主动机)

    Detect the Virus Time Limit: 2 Seconds      Memory Limit: 65536 KB One day, Nobita found that his co ...

  3. POJ 2778 DNA Sequence (AC自己主动机 + dp)

    DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...

  4. hdu4758 Walk Through Squares (AC自己主动机+DP)

    Walk Through Squares Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...

  5. poj 3691 DNA repair(AC自己主动机+dp)

    DNA repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5877   Accepted: 2760 Descri ...

  6. hdu4057 Rescue the Rabbit(AC自己主动机+DP)

    Rescue the Rabbit Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

  7. HDU - 4758 Walk Through Squares (AC自己主动机+DP)

    Description   On the beaming day of 60th anniversary of NJUST, as a military college which was Secon ...

  8. HDU - 2825 Wireless Password(AC自己主动机+DP)

    Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...

  9. Hdu 3341 Lost&#39;s revenge (ac+自己主动机dp+hash)

    标题效果: 举个很多种DNA弦,每个字符串值值至1.最后,一个长字符串.要安排你最后一次另一个字符串,使其没事子值和最大. IDEAS: 首先easy我们的想法是想搜索的!管她3721..直接一个字符 ...

随机推荐

  1. [转]Linux之ACL权限

    转自:http://www.2cto.com/os/201110/108736.html 引言 前面的内容中,我们讲到传统的权限仅有三种身份(owner,group,others)搭配三种权限(r,w ...

  2. BOM 标记

    BOM 是 Byte Order Mark 的简称,即字节序标记.用于标记文本流: 表示文本流的字节顺序,是小端序(little-endian)还是大端序(big-endian); 表示文本流是 Un ...

  3. Android 微信分享图片

    "; //微信 APPID private IWXAPI iwxapi; private void regToWx() { iwxapi = WXAPIFactory.createWXAPI ...

  4. drupal 8——打补丁(patch)

    druapl 的核心可能会有漏洞,这时就需要我们去打补丁.很多补丁都已经有人写好了,我这里讲的就是如何去打这些已经写好的补丁. 对于这个问题:drupal8 核心有bug导致了两个相同的错误提示的出现 ...

  5. PHP基础知识测试题及解析

      本试题共40道选择题,10道判断题,考试时间1个半小时 一:选择题(单项选择,每题2分): 1. LAMP具体结构不包含下面哪种(A ) A:Windows系统 B:Apache服务器 C:MyS ...

  6. 4星|《超级技术:改变未来社会和商业的技术趋势》:AI对人友好吗

    超级技术:改变未来社会和商业的技术趋势 多位专家或经济学人编辑关于未来的预测,梅琳达·盖茨写了其中一章.在同类书中属于水平比较高的,专家只写自己熟悉的领域,分析与预测有理有据而不仅仅是畅想性质. 以下 ...

  7. 脚本添加删除nginx配置中的内容

    [root@nodejs script]# more editnginx.sh #!/bin/bash # function back_check(){ # 备份配置和覆盖配置文件 cp -rf /e ...

  8. Android控件的继承关系

    1.View,ViewGroup >View: }1.所有高级UI组件都继承View类而实现的 }2.一个View在屏幕上占据一块矩形区域 }3. 负责渲染 }4.负责处理发生的事件 }5.设置 ...

  9. 浏览器的 local storage

    浏览器 local storage      本地存储 session storage    会话存储 cookies                  本地存储 1.     local stora ...

  10. 单实例redis分布式锁的简单实现

    redis分布式锁的基本功能包括, 同一刻只能有一个人占有锁, 当锁被其他人占用时, 获取者可以等待他人释放锁, 此外锁本身必须能超时自动释放. 直接上java代码, 如下: package com. ...