HDU 2457 DNA repair(AC自动机+DP)
来源:互联网 发布:剑侠情缘手游数据互通 编辑:程序博客网 时间:2024/06/16 00:09
HDU 2457 DNA repair(AC自动机+DP)
http://acm.hdu.edu.cn/showproblem.php?pid=2457
题意:
给你N个模板串,并且给你一个文本串,现在问你这个文本串最少需要改变几个字符才能使得它不包含任何模板串.(以上字符只由A,T,G,C构成).
分析:
本题初看确实不知道怎么做,和之前做的题目都不一样.
现在我们令dp[i][j]=x表示当前在自动机的i号节点,且走了长为j的路了,且过程中都不经过单词节点的情况下,与文本串的前j个字符不同点最少有x个.(仔细体会dp[i][j]的定义).
初值dp[i][j]=-1,dp[0][0]=0.
dp[i][j] = min( dp[k][j-1] + v ) 从k可以走到i,且i和k都是非后缀单词.
设从k走到i的那条边的字符为x,如果x==s[j-1],那么v=0.否则v=1.
AC代码:1A
#include<iostream>#include<queue>#include<map>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<string>using namespace std;const int maxnode=1000+20;const int sigma_size=4;//后面读入int n,m;int len;char str[maxnode];struct AC_Automata{ int ch[maxnode][sigma_size]; int match[maxnode];//单词的结束结点记录这个单词的权值 int f[maxnode]; int sz; int dp[maxnode][maxnode]; map<char,int>mp; char signum[4]; void init() { sz=1; memset(ch[0],0,sizeof(ch[0])); match[0]=f[0]=0; mp['A']=0,signum[0]='A'; mp['T']=1,signum[1]='T'; mp['G']=2,signum[2]='G'; mp['C']=3,signum[3]='C'; } void insert(char *s)//v表示第几个单词 { int n=strlen(s),u=0; for(int i=0;i<n;i++) { int id=mp[s[i]]; if(ch[u][id]==0) { ch[u][id]=sz; memset(ch[sz],0,sizeof(ch[sz])); match[sz++]=0; } u=ch[u][id]; } match[u]|=1; } void getFail() { f[0]=0; queue<int> q; for(int i=0;i<sigma_size;i++) { int u=ch[0][i]; if(u) { f[u]=0; q.push(u); } } while(!q.empty()) { int r=q.front();q.pop(); for(int i=0;i<sigma_size;i++) { int u=ch[r][i]; if(!u){ ch[r][i]=ch[f[r]][i]; continue; } q.push(u); int v=f[r]; while(v && ch[v][i]==0) v=f[v]; f[u]=ch[v][i]; match[u] |= match[f[u]]; } } } int solve() { int ans=-1; for(int i=0;i<sz;i++){for(int j=0;j<=len;j++){dp[i][j]=-1;}}dp[0][0]=0;for(int lens=0;lens<len;lens++){for(int i=0;i<sz;i++){if(match[i]==0&&dp[i][lens]!=-1){for(int j=0;j<sigma_size;j++){if(match[ch[i][j]]==0){int k=ch[i][j];int v=(str[lens]==signum[j])?0:1;//当前结点是否需要修改if(dp[k][lens+1]!=-1){dp[k][lens+1]=min(dp[i][lens]+v,dp[k][lens+1]);}else{dp[k][lens+1]=dp[i][lens]+v;}if(lens+1==len){if(ans!=-1){ans=min(ans,dp[k][len]);}elseans=dp[k][len];}}}}}}return ans; }};AC_Automata ac;int main(){int kase=0; while(~scanf("%d",&n)&&n){ac.init();for(int i=0;i<n;i++){scanf("%s",str);ac.insert(str);}scanf("%s",str);len=strlen(str);ac.getFail(); printf("Case %d: %d\n",++kase,ac.solve());} return 0;}
阅读全文
0 0
- hdu 2457 DNA repair(AC自动机+DP)
- HDU 2457 DNA repair(AC自动机+DP)
- 【HDU】2457 DNA repair AC自动机+DP
- hdu 2457 DNA repair ac自动机+dp
- Hdu 2457 DNA repair (ac自动机+dp)
- [AC自动机+dp] hdu 2457 DNA repair
- hdu 2457 DNA repair(AC自动机+DP)
- hdu 2457 DNA repair (ac自动机+dp)
- hdu 2457 DNA repair(ac自动机+dp)
- HDU 2457 DNA repair AC自动机+DP
- HDU - 2457 DNA repair AC自动机+dp
- Hdu 2457 DNA repair AC自动机+DP
- HDU 2457 DNA repair(AC自动机+DP)
- hdu DNA repair(AC自动机+DP)
- HDU 2457 DNA repair(AC自动机+DP)
- Poj 3691 & Hdu 2457 DNA repair (AC自动机+DP)
- HDU 2457 DNA repair(AC自动机 + DP 入门)
- POJ 3691 & HDU 2457 DNA repair (AC自动机,DP)
- Pointers on C——6 Pointers.10
- android使用Gradle统一依赖库的版本号
- Linux内核中的Proc文件系统(一)
- Running QCL (Quantum Computation Language) on Ubuntu
- Pointers on C——6 Pointers.11
- HDU 2457 DNA repair(AC自动机+DP)
- Pointers on C——6 Pointers.12
- 【MVP+Retrofit+RxAndroid+dagger2】读易读应用框架笔记(一)MVP应用篇
- 图片宽度自适应
- Pointers on C——6 Pointers.13
- 【C++】C++运算符重载-基础
- Pointers on C——6 Pointers.14
- 1020. 月饼 (25)71min
- 31章