Codeforces 86C Genetic engineering (AC自己主动机+dp)
题目大意:
要求构造一个串,使得这个串是由所给的串相连接构成,连接能够有重叠的部分。
思路分析:
首先用所给的串建立自己主动机,每一个单词节点记录当前节点可以达到的最长后缀。
開始的时候想的是dp[i][j]表示长度为i,走到自己主动机的j节点的答案。
可是显然既然是能够反复覆盖的,那么每个节点的dp值都并非最优的。由于能够从一个地方截断去连接另外一个串。
所以正确姿势就是dp [i] [j] [k] 表示构造到了长度为 i 的串, 如今这个串后面有k 个字符是没有找到有效的节点的,然后在自己主动机上走到了j。
那么转移的时候,就有两种情况。
isword >= k+1。
。。
为什么是k+1 由于我们如今是去找的儿子节点,已经加1了。这种话就是这个节点能够全然覆盖没有匹配到的k个。换句话说就是让后面的k个字符找到了合法节点去匹配。那么就转移到dp [i+1] [j->next] [0]...
否则,假设k+1<=10 那么就让后面这个继续失配,那么久直接转移到 dp [i+1][j->next][k+1]...
最后累加答案。
#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 = 4;
int rev[256];
struct trie
{
struct trie *fail;
struct trie *next[max_next];
int isword;
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++;
return temp;
}
void init()
{
idx=0;
root=New();
}
void Insert(trie *root,char *word,int len){
trie *t=root;
for(int i=0;i<len;i++){
if(t->next[rev[word[i]]]==NULL)
t->next[rev[word[i]]]=New();
t=t->next[rev[word[i]]];
}
t->isword=len;
}
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);
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,sb;
string cq[55];
char word[55];
int dp[1005][105][11];
void add(int &a,int b)
{
a+=b;
if(a>=mod)a-=mod;
}
int solve(int L)
{
memset(dp,0,sizeof dp);
dp[0][0][0]=1;
for(int i=0;i<L;i++)
{
for(int j=0;j<sa.idx;j++)
{
for(int k=0;k<10;k++)
{
for(int d=0;d<4;d++)
{
if(sa.ac[j].next[d]->isword>=k+1)
add(dp[i+1][sa.ac[j].next[d]->index][0],dp[i][j][k]);
else if(k+1<=10)
add(dp[i+1][sa.ac[j].next[d]->index][k+1],dp[i][j][k]);
}
}
}
}
int ans=0;
for(int i=0;i<sa.idx;i++)
{
add(ans,dp[L][i][0]);
}
return ans;
} int main()
{
rev['A']=0;
rev['C']=1;
rev['G']=2;
rev['T']=3;
int m,L;
while(cin>>L>>m)
{
sa.init();
for(int i=1;i<=m;i++)
{
cin>>word;
sa.Insert(sa.root,word,strlen(word));
}
sa.acbuild(sa.root);
printf("%d\n",solve(L));
}
return 0;
}
Codeforces 86C Genetic engineering (AC自己主动机+dp)的更多相关文章
- hdu4758 Walk Through Squares (AC自己主动机+DP)
Walk Through Squares Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...
- HDU - 4758 Walk Through Squares (AC自己主动机+DP)
Description On the beaming day of 60th anniversary of NJUST, as a military college which was Secon ...
- POJ 2778 DNA Sequence (AC自己主动机 + dp)
DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...
- HDU - 2825 Wireless Password(AC自己主动机+DP)
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
- Hdu 3341 Lost's revenge (ac+自己主动机dp+hash)
标题效果: 举个很多种DNA弦,每个字符串值值至1.最后,一个长字符串.要安排你最后一次另一个字符串,使其没事子值和最大. IDEAS: 首先easy我们的想法是想搜索的!管她3721..直接一个字符 ...
- poj 3691 DNA repair(AC自己主动机+dp)
DNA repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5877 Accepted: 2760 Descri ...
- hdu4057 Rescue the Rabbit(AC自己主动机+DP)
Rescue the Rabbit Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- Zoj 3535 Gao the String II (AC自己主动机+dp)
题目大意: 用集合A中的串构造出一个串,使之让很多其它的setB中的串成为他的子串. 思路分析: 和 Codeforces 86C 几乎相同. 只是这里是要用A中的构造. 先用A 和 B的串构造一个自 ...
- HDU - 4511 小明系列故事――女友的考验(AC自己主动机+DP)
Description 最终放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候.女朋友告诉他.她在电影院等他,小明过来的路线必须满足给定的规则: 1.如果小明 ...
随机推荐
- 【canvas】N角光阑
这回把光阑代码统一了,修改angleCount的数目为3就是三角光阑,angleCount的数目为4就是四角光阑,angleCount的数目为6就是六角光阑,目前代码中是12角光阑. 图示: 代码: ...
- 关于SQL 行转列的办法
公司实施小姑娘要我写一个SQL给她 需求如下: 现在有表A,字段 id code parentid backres,现数据如下 id code parentid backres 1 A 5 2 B 5 ...
- 微信小程序 - 获取所在位置(省、市、区)
实现步骤 1. 获取当前经纬度 2. 调用腾讯(百度.高德)地图对应的请求地址,一般都会有独一的key, 譬如 腾讯地图调用地址: https://apis.map.qq.com/ws/geocode ...
- PHP高级教程-文件上传
PHP 文件上传 通过 PHP,可以把文件上传到服务器. 本章节实例在 test 项目下完成,目录结构为: test |-----upload # 文件上传的目录 |-----form.html # ...
- Java的类名与文件名必须一致(转)
原文:http://blog.csdn.net/shaoxiaoning/article/details/40424087 1.Java保存的文件名必须与类名一致: 2.如果文件中只有一个类,文件名必 ...
- JavaBean(web基础学习笔记十二)
一.JavaBean简介 JavaBean是使用Java语言开发的一个可重用的组件,在JSP的开发中可以使用JavaBean减少重复代码,使整个JSP代码的开发更简洁.JSP搭配JavaBean来使用 ...
- 解析 神奇的 Object.defineProperty
这个方法了不起啊..vue.js和avalon.js 都是通过它实现双向绑定的..而且Object.observe也被草案发起人撤回了..所以defineProperty更有必要了解一下了几行代码看他 ...
- jquery插件开发通用框架
2017-07-24 更新:增加单例模式. jquery插件开发框架代码: /* * 插件编写说明: * 1.插件命名:jquery.[插件名].js,如jquery.plugin.js * 2.对象 ...
- 在Ubuntu下设置默认编辑器
在默认情况下,Ubuntu 系统会为用户预设程序.就拿文本编辑器来说吧,Ubuntu 预设的是 Nano,对某些朋友来说,使用 Vim 可能更得心应手些.那么如何更改这些预设的程序呢? 你可以使用 s ...
- 使用openssl进行证书格式转换
各类证书由于存储的内容不同(如是否包含公钥/私钥是否加密存储/单一证书或多证书等).采用编 码不同(DER/BASE64).标准不同(如PEM/PKCS),所以尽管X.509标准规定了证书内容规范,但 ...