题目大概是给几个DNA片段,求构造一个长度n的字符串的方案数,要求这个字符串每个位置的字符都属于某个包含于此字符串的DNA片段。

把那些DNA片段建一个AC自动机。考虑状态的表示:

  • dp[len][x][k]表示长度len且后缀状态为自动机结点x且后k位还不满足要求的方案数
  • 然后转移就是向自动机上四个方向的结点走,如果下一步结点x'是某DNA的后缀且长度比k大,那就是转移到dp[len+1][x'][0]否则转移到dp[len+1][x'][k+1]。另外因为DNA最长10,所以第三维k不会超过10。

不过我还是看了别人代码才A掉这题。。忽略了某个结点不是一个DNA片段但其后缀可能是个DNA片段。

 #include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int tn,ch[][],fail[],flag[];
int idx[];
void insert(char *s,int k){
int x=;
for(int i=; s[i]; ++i){
int y=idx[s[i]];
if(ch[x][y]==) ch[x][y]=++tn;
x=ch[x][y];
}
flag[x]=k;
}
void getFail(){
queue<int> que;
for(int i=; i<; ++i){
if(ch[][i]) que.push(ch[][i]);
}
while(!que.empty()){
int x=que.front(); que.pop();
for(int i=; i<; ++i){
if(ch[x][i]){
que.push(ch[x][i]);
fail[ch[x][i]]=ch[fail[x]][i];
flag[ch[x][i]]=max(flag[ch[x][i]],flag[ch[fail[x]][i]]);
} else ch[x][i]=ch[fail[x]][i];
}
}
}
struct Node{
int len,x,k;
Node(int _l=,int _x=,int _k=):len(_l),x(_x),k(_k){}
};
int d[][][];
bool vis[][][];
int main(){
idx['A']=; idx['C']=; idx['G']=; idx['T']=;
char str[];
int n,m;
scanf("%d%d",&n,&m);
for(int i=; i<m; ++i){
scanf("%s",str);
insert(str,strlen(str));
}
getFail();
d[][][]=;
vis[][][]=;
queue<Node> que;
que.push(Node(,,));
while(!que.empty()){
Node nd=que.front(); que.pop();
int len=nd.len,x=nd.x,k=nd.k;
if(len==n) continue;
for(int i=; i<; ++i){
if(k+<=flag[ch[x][i]]){
d[len+][ch[x][i]][]+=d[len][x][k];
d[len+][ch[x][i]][]%=;
if(!vis[len+][ch[x][i]][]){
vis[len+][ch[x][i]][]=;
que.push(Node(len+,ch[x][i],));
}
}else{
if(k>=) continue;
d[len+][ch[x][i]][k+]+=d[len][x][k];
d[len+][ch[x][i]][k+]%=;
if(!vis[len+][ch[x][i]][k+]){
vis[len+][ch[x][i]][k+]=;
que.push(Node(len+,ch[x][i],k+));
}
}
}
//vis[len][x][k]=0; //DAG
}
int res=;
for(int i=; i<=tn; ++i){
res+=d[n][i][];
res%=;
}
printf("%d",res);
return ;
}

Codeforces 86C Genetic engineering(AC自动机+DP)的更多相关文章

  1. Codeforces 86C Genetic engineering (AC自己主动机+dp)

    题目大意: 要求构造一个串,使得这个串是由所给的串相连接构成,连接能够有重叠的部分. 思路分析: 首先用所给的串建立自己主动机,每一个单词节点记录当前节点可以达到的最长后缀. 開始的时候想的是dp[i ...

  2. Codeforces 1015F Bracket Substring AC自动机 + dp

    Bracket Substring 这么垃圾的题怎么以前都不会写啊, 现在一眼怎么就会啊.... 考虑dp[ i ][ j ][ k ][ op ] 表示 已经填了 i 个空格, 末尾串匹配到 所给串 ...

  3. HDU 4758 Walk Through Squares (2013南京网络赛1011题,AC自动机+DP)

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

  4. POJ1625 Censored!(AC自动机+DP)

    题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...

  5. HDU2296 Ring(AC自动机+DP)

    题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...

  6. HDU2457 DNA repair(AC自动机+DP)

    题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...

  7. hdu 4117 GRE Words AC自动机DP

    题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...

  8. hdu 2457(ac自动机+dp)

    题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...

  9. HDU 2425 DNA repair (AC自动机+DP)

    DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. Python ===if while for语句 以及一个小小网络爬虫实例

    if分支语句 >>> count=89 >>> if count==89: print count 89                          #单分支 ...

  2. show processlist 其中status详解(适用于所有概况)

    mysql show processlist分析 2011-04-11 16:13:00 分类: Mysql/postgreSQL mysql> show processlist; +—–+—— ...

  3. Unity 烘焙材质到单一贴图的脚本

    原地址:http://www.cocoachina.com/gamedev/gameengine/2011/0406/2756.html 这个脚本由 CocoaChina 版主 “四角钱” 分享,可以 ...

  4. UIView 注意问题

    1. UIView.userInteractionEnabled UIView.userInteractionEnabled默认值是YES http://blog.csdn.net/studyreco ...

  5. 把 表拷贝到test测试数据库

    (文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) bundle exec rake db:schema:load RAILS_ENV=test   注 ...

  6. chrome控制台支持多行js模式

    shift + 回车 是换行 转自: http://zhidao.baidu.com/link?url=MYjGRwvVQYJwnr38VTHPJdzRNtF1COyqpeuAtBYbxFYJcu6p ...

  7. Copy List with Random Pointer

    A linked list is given such that each node contains an additional random pointer which could point t ...

  8. iOS 中的Push Notifications简单实现(APNS)

    Android中的通知只有一种,就是Local Notifications,而iOS中除了Local Notifications外,还有一种Push Notifications.ios的这2种noti ...

  9. Java for LeetCode 061 Rotate List

    Given a list, rotate the list to the right by k places, where k is non-negative. For example: Given ...

  10. [Android Pro] Android fastboot刷机和获取Root权限

    参考文章: https://developers.google.com/android/nexus/images 转载自:    http://www.inexus.co/article-1280-1 ...