【xsy1012】KSHKM的基因工程 AC自动机DP
题目大意:给你n个串pi,最后再给一个串s(字符集均为A,C,G,T四个字符中的一个)。问你串s最少要更改多少个字符(更改后的字符也只能是ACGT),才能满足s中不包含pi(1≤i≤n)
数据范围:n≤50,|p|≤20,|s|≤100。不超过100组数据。
此题显然是一个AC自动机DP题。
我们首先建出字符串集合p的AC自动机。
不难发现,这个自动机中有很多个节点是不能被遍历到的(如果遍历到了串就会包含某些不合法串)
设f[i][j]表示我们已经扫描完了串s中前i个字符,且当前遍历到了自动机第j号点时,最少需要改变的字符数量。
然后枚举我们要在第i+1位填什么字符,是否会增加贡献。
也就是说,我们可以用f[i][j]的值来更新f[i+1][ch[j][char]],其中ch[j][char]表示在j号节点往下填字符char会跑到哪个点(详见代码)
然后就没有了
复杂度:O(nps)。
1 #include<bits/stdc++.h> 2 #define M 1005 3 #define INF 16843009 4 #define fmin(x,y) ((x)>(y)?(x)=(y):0) 5 using namespace std; 6 7 int id[128]={0}; 8 9 struct trie{int a[4],fail,no;}a[M];int use=0; 10 void add(char c[]){ 11 int len=strlen(c),now=0; 12 for(int i=0;i<len;i++){ 13 int k=id[c[i]]; 14 if(a[now].a[k]) now=a[now].a[k]; 15 else a[now].a[k]=++use,now=use; 16 } 17 a[now].no=1; 18 } 19 void makefail(){ 20 queue<int> q; q.push(0); 21 while(!q.empty()){ 22 int u=q.front(); q.pop(); 23 for(int i=0;i<4;i++) if(a[u].a[i]){ 24 a[a[u].a[i]].no|=a[u].no; 25 q.push(a[u].a[i]); 26 if(u){ 27 int f=a[u].fail; 28 while(f&&a[f].a[i]==0) f=a[f].fail; 29 a[a[u].a[i]].fail=a[f].a[i]; 30 a[a[u].a[i]].no|=a[a[f].a[i]].no; 31 } 32 }else{ 33 a[u].a[i]=a[a[u].fail].a[i]; 34 } 35 } 36 } 37 38 int s[M]={0},f[M][M]={0};char str[M]={0}; 39 40 int main(){ 41 id['A']=0; id['C']=1; id['G']=2; id['T']=3; 42 for(int cas=1;;cas++){ 43 memset(s,0,sizeof(s)); memset(a,0,sizeof(a)); use=0; 44 int n; scanf("%d",&n); 45 if(n==0) return 0; 46 for(int i=1;i<=n;i++){ 47 scanf("%s",str); 48 add(str); 49 } 50 makefail(); 51 scanf("%s",str+1); int len=strlen(str+1); 52 for(int i=1;i<=len;i++) s[i]=id[str[i]]; 53 memset(f,1,sizeof(f)); f[0][0]=0; 54 for(int i=0;i<len;i++){ 55 for(int j=0;j<=use;j++) 56 if(f[i][j]!=INF){ 57 for(int k=0;k<4;k++){ 58 int pls=(k!=s[i+1]); 59 if(a[a[j].a[k]].no) continue; 60 fmin(f[i+1][a[j].a[k]],f[i][j]+pls); 61 } 62 } 63 } 64 int minn=INF; 65 for(int j=0;j<=use;j++) if(a[j].no==0) 66 fmin(minn,f[len][j]); 67 printf("Case %d: ",cas); 68 if(minn==INF) cout<<-1<<endl; 69 else cout<<minn<<endl; 70 } 71 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!