hdu 2457 DNA repair (ac自动机+记忆化搜索)
2015-09-06 13:06
330 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2457
题意:给出N个DNA序列(只包含’A‘,'T','G','C'四种字符),然给一段DNA序列S,问最少改多少个字符使得这个DNA序列不包含前面任意一个DNA序列。
分析:将前面N个DNA序列建ac自动机,然后找出禁止走的位置。定义dp[i][j],i表示当前在字符串S的位置,j表示对应在ac机上的位置,dp[i][j]表示最小修改字符数。
代码:
题意:给出N个DNA序列(只包含’A‘,'T','G','C'四种字符),然给一段DNA序列S,问最少改多少个字符使得这个DNA序列不包含前面任意一个DNA序列。
分析:将前面N个DNA序列建ac自动机,然后找出禁止走的位置。定义dp[i][j],i表示当前在字符串S的位置,j表示对应在ac机上的位置,dp[i][j]表示最小修改字符数。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int INF = 2e9+7; const int maxn = 2015; const int kd = 4; int ncase; struct trie { int son[maxn][kd],fail[maxn],fbd[maxn]; int cnt,root; int SL,ERROR,dp[maxn>>1][maxn>>1]; char s[maxn]; int newnode() { fill(son[cnt],son[cnt]+kd,-1); fbd[cnt]=0; return cnt++; } void Init() { cnt=0; root=newnode(); } int idx(char ch) { switch(ch) { case 'A' : return 0; case 'C' : return 1; case 'G' : return 2; case 'T' : return 3; } return -1; } void Insert(char str[]) { int now=root,i,index; for(i=0;str[i];i++) { index=idx(str[i]); if(son[now][index]==-1) son[now][index]=newnode(); now=son[now][index]; } fbd[now]=1; } void findfail() { queue <int> q; int i,temp; fail[root]=root; for(i=0;i<kd;i++) if(son[root][i]==-1) son[root][i]=root; else { fail[son[root][i]]=root; q.push(son[root][i]); } while(!q.empty()) { temp=q.front(); q.pop(); fbd[temp]|=fbd[fail[temp]]; for(i=0;i<kd;i++) if(son[temp][i]==-1) son[temp][i]=son[fail[temp]][i]; else { fail[son[temp][i]]=son[fail[temp]][i]; q.push(son[temp][i]); } } } int Next(int cur,int x) { if(fbd[cur] || fbd[son[cur][x]]) return -1; return son[cur][x]; } int DFS(int len,int cur) { if(len==SL) return 0; if(dp[len][cur]!=-1) return dp[len][cur]; int ret[4]={INF,INF,INF,INF},index,temp; for(int i=0;i<kd;i++) { temp=Next(cur,i); if(temp!=-1) { index=idx(s[len]); if(index==i) ret[i]=DFS(len+1,temp); else ret[i]=DFS(len+1,temp)+1; } } for(int i=1;i<kd;i++) if(ret[i]<ret[0]) ret[0]=ret[i]; return dp[len][cur]=ret[0]; } void solve() { SL=strlen(s); memset(dp,-1,sizeof(dp)); int ans=DFS(0,root); if(ans>=INF) printf("Case %d: %d\n",ncase++,-1); else printf("Case %d: %d\n",ncase++,ans); } }ac; int main() { int n,i,j; ncase=1; while(scanf("%d",&n)!=EOF&&n) { ac.Init(); while(n--) { scanf("%s",ac.s); ac.Insert(ac.s); } ac.findfail(); scanf("%s",ac.s); ac.solve(); } return 0; }
相关文章推荐
- AI学习笔记(01)
- InvokeMember 使用(转http://blog.csdn.net/gooer/article/details/2927113)
- windows下成功编译Cairo,Compiling Cairo for Windows
- Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别
- 人和机器的视觉体验:为什么人工智能“会做梦”?
- assign,retain,copy,weak,strong,readonly,nonatomic ,atomic 8个属性的特征
- [LeetCode] Paint House I & II
- “The signin method you’re trying to use isn’t allowed&rdquo
- Xcode6中如何去掉默认的Main.storyboard
- Linux-2.6 open()打开文件涉及的内核处理和数据结构分析 http://blog.csdn.net/ordeder/article/details/24420637
- NSBundle的使用,注意mainBundle和Custom Bundle的区别
- twistd工具搭建mail服务器
- Find and Retain Passionate Problem Solvers
- 20150905日课程作业(计划任务mail,at,cron,)
- 计划任务和周期任务mail,at,batch,atq, atrm, cron, crontab
- HDU 3376 Matrix Again(费用流)
- INSTALL_FAILED_NO_MATCHING_ABIS 的解决办法
- 漫谈游戏中的人工智能
- HDU 1021 Fibonacci Again(数论)
- hdu 4308 Saving Princess claire_