题目大意:

用集合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. jsp动态网页开发基础

    JSP基础语法 jsp页面元素构成 jsp页面组成部分有:指令,注释,静态内容,表达式,小脚本,声明. 1.表达式<%=     %> 2.小脚本<%       %> 3.声 ...

  2. ASP.NET AJAX应用

    ASP.NET AJAX能够快速地创建具有丰富的用户体验的页面,而且这些页面由可靠和熟悉的用户接口元素组成,包括一个能快速响应的用户体验和熟悉的用户元素. 使用ASP.NET  AJAX,可以改善We ...

  3. Jquery EasyUI环境下设置下拉框选中指定选项

    前提: 要求点击某个按钮就将所有的下拉框都设置为选中第一个选项,因此,指定索引是最好的做法 尝试过的做法: html代码如下(easyui 的写法) <select class="ea ...

  4. 深入浅出的 SQL Server 查询优化

    目前网络数据库的应用已经成为最为广泛的应用之一了,并且关于数据库的安全性,性能都是企业最为关心的事情.数据库渐渐成为企业的命脉,优化查询就解决了每个关于数据库应用的性能问题,在这里microsoft ...

  5. CSS——img

    img标签初始化:在低版本的ie浏览器会自带边框,所以建议border:0px.

  6. spring 将配置文件中的值注入 属性

    1.编写配置文件 #债权转让 #默认周期 必须大于0 credit.defaultDuration=1 #最小转让金额(元) credit.minBidAmount=1.00 #最小转让时间 到期时间 ...

  7. 【译】x86程序员手册20-6.3.4门描述符守卫程序入口

    6.3.4 Gate Descriptors Guard Procedure Entry Points 门描述符守卫程序入口 To provide protection for control tra ...

  8. Codeforces_733D

    D. Kostya the Sculptor time limit per test 3 seconds memory limit per test 256 megabytes input stand ...

  9. maxtrid 3D视差

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. Java-Class-Miniprogram:com.ylbtech.common.utils.miniprogram.TemplateMessage

    ylbtech-Java-Class-Miniprogram:com.ylbtech.common.utils.miniprogram.TemplateMessage 1.返回顶部 1.1. pack ...