Codeforces 86C Genetic engineering(AC自动机+DP)
题目大概是给几个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)的更多相关文章
- Codeforces 86C Genetic engineering (AC自己主动机+dp)
题目大意: 要求构造一个串,使得这个串是由所给的串相连接构成,连接能够有重叠的部分. 思路分析: 首先用所给的串建立自己主动机,每一个单词节点记录当前节点可以达到的最长后缀. 開始的时候想的是dp[i ...
- Codeforces 1015F Bracket Substring AC自动机 + dp
Bracket Substring 这么垃圾的题怎么以前都不会写啊, 现在一眼怎么就会啊.... 考虑dp[ i ][ j ][ k ][ op ] 表示 已经填了 i 个空格, 末尾串匹配到 所给串 ...
- 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 ...
- POJ1625 Censored!(AC自动机+DP)
题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...
- HDU2296 Ring(AC自动机+DP)
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- hdu 4117 GRE Words AC自动机DP
题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...
- hdu 2457(ac自动机+dp)
题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...
- HDU 2425 DNA repair (AC自动机+DP)
DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- Python ===if while for语句 以及一个小小网络爬虫实例
if分支语句 >>> count=89 >>> if count==89: print count 89 #单分支 ...
- show processlist 其中status详解(适用于所有概况)
mysql show processlist分析 2011-04-11 16:13:00 分类: Mysql/postgreSQL mysql> show processlist; +—–+—— ...
- Unity 烘焙材质到单一贴图的脚本
原地址:http://www.cocoachina.com/gamedev/gameengine/2011/0406/2756.html 这个脚本由 CocoaChina 版主 “四角钱” 分享,可以 ...
- UIView 注意问题
1. UIView.userInteractionEnabled UIView.userInteractionEnabled默认值是YES http://blog.csdn.net/studyreco ...
- 把 表拷贝到test测试数据库
(文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) bundle exec rake db:schema:load RAILS_ENV=test 注 ...
- chrome控制台支持多行js模式
shift + 回车 是换行 转自: http://zhidao.baidu.com/link?url=MYjGRwvVQYJwnr38VTHPJdzRNtF1COyqpeuAtBYbxFYJcu6p ...
- Copy List with Random Pointer
A linked list is given such that each node contains an additional random pointer which could point t ...
- iOS 中的Push Notifications简单实现(APNS)
Android中的通知只有一种,就是Local Notifications,而iOS中除了Local Notifications外,还有一种Push Notifications.ios的这2种noti ...
- 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 ...
- [Android Pro] Android fastboot刷机和获取Root权限
参考文章: https://developers.google.com/android/nexus/images 转载自: http://www.inexus.co/article-1280-1 ...