题目大意:

用集合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. wordpress 你所不知道的固定链接设置方法,设置适合自己的个性固定链接,适合SEO

    %year% 年份,四位数字,例如2004年  %monthnum% 一年的月份,例如05  %day% 一个月的日子,例如28  %hour% 一天中的小时,例如15  %minute% 小时,例如 ...

  2. React Native组件间通信

    React Native组件间通信 React Native组件的关系有:父子关系.无直接关系.组件间通信主要针对这两类来讨论. 一.父组件和子组件之间通信 父组件向子组件传递消息.数据通过对子组件的 ...

  3. 屏蔽scrollview的滚动

    外层有scrollview时,手指移动方向跟滚动条方向相同时,会导致scrollview的滚动.此时如果不想滚动的话,可以在要接受ontouch的子视图,或者子子视图中的touch监听里加上v.get ...

  4. html——特殊字符

  5. 快速学习mybatis框架

    一.介绍Mybatis(主要从以下两点进行介绍) 1.MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动 ...

  6. VHDL_ADC之cic_diffcell

    library IEEE; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library edclib; use edclib.pkg_ ...

  7. transactoin

    hibernate对数据的操作是封装在事务当中,并且默认是非自动提交方式.所以用session保存对象时,如果不开启事务,并且手工提交事务,对象并不会真正保存在数据库中.

  8. 通过offset值的设置使html元素对齐

    今天是我第一次写这个随笔,为了记录我发现的一个jquery的offset的值的问题. 这个offset的值会因为页面标签是否处于隐藏状态而表现出不同的值,隐藏状态时,offset的值是相对于直接父亲的 ...

  9. ubuntu14.04禁用USB外存储设备

    ubuntu 14.04中禁用usb外存储设备: 在网上找了很多方法,大概都是下面的命令,而实际测试的时候没有什么作用. gsettings set org.gnome.desktop.media-h ...

  10. mysql跟java时间类型转换

    参照这个就行了,这个对应注入类型.===========java注入数据库==========java类型 mysql类型 成功与否date date yesdate time nodate time ...