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.如果小明 ...
随机推荐
- ArcGIS Pro体验04——菜单栏
对菜单栏进行熟悉一下: 1.地图菜单 剪切板(Clipboard):剪切(Cut).复制(Copy).粘贴(Paste),这些不用说了,在ArcMap中是放在"编辑"菜单下面的.当 ...
- 开源 免费 java CMS - FreeCMS1.5-数据对象-job
下载地址:http://code.google.com/p/freecms/ job 从FreeCMS 1.5 开始支持 在使用职位相关标签时,标签会封装job供页面调用. 属性 说明 id id s ...
- Struts2(五)Action二配置
一.method参数 action package com.pb.web.action; public class HourseAction { public String add(){ System ...
- Java从零开始学六(运算符)
运算符 一.赋值运算符号 No. 赋值运算符号 描述 1 = 赋值 int num=22; System.out.println("num= "+num); num=num-3; ...
- OA项目实战学习(7)——初始化数据&权限配置显示
详细有哪些功能: 初始化数据 权限数据. 超级管理员. Installer.java package cn.xbmu.oa.install; import javax.annotation.Resou ...
- Oracle 12c CDB PDB
先说基本用法: 先按11G之前进行 conn / as sysdba; create user test identifed by test; ORA-65096: 公用用户名或角色名无效. 查官方文 ...
- [Unity-1] Unity简单介绍
Unity是一套包含图形.声音.物理等功能的游戏引擎,提供了一个强大的关卡编辑器.支持大部分主流3D软件格式,使用C#或者JavaScript等高级语言实现脚本功能.使开发人员无需了解底层复杂技术,高 ...
- 基于LumiSoft.Net.dll发、收、删邮件
发邮件: using LumiSoft.Net.SMTP.Client; Mime m = new Mime(); MimeEntity mainEntity = m.MainEntity; // F ...
- lambda 2
# -*- coding: utf-8 -*- #python 27 #xiaodeng def action(x): return (lambda y:x+y) act=action(99) pri ...
- 在阿里云上进行Docker集群的自动弹性伸缩
摘要: 在刚刚结束的云栖大会上,阿里云容器服务演示了容器的自动弹性伸缩,能够从容应对互联网应用的峰值流量.阿里云容器服务不仅支持容器级别的自动弹性伸缩,也支持集群节点级别的自动弹性伸缩.从而真正做到从 ...