【HDOJ3341】Lost's revenge(AC自动机,DP)
题意:给出一个n个模式串,一个目标串,问把目标串重新排位最多能产生多少个模式串,可以重叠且所有串只包含A C G T。
n<=10,len[i]<=10
len(s)<=40
Cas<=30
思路:TLE,估计被卡常了
可以将题意理解为重新构造一个ACGT个数都与原目标串相同的新串,则目标串中有用的信息只有ACGT个数
建出Trie图,跑一遍AC自动机,再用一个二维dp[i,j]表示trie上i号节点,字母使用情况为j的模式串最多出现次数
其中j为状态压缩量,是一个四维的量压成一维,因为不压的话会MLE
dp[v,h(a,b,c,d)]=max(dp[v,h(a,b,c,d)],dp[u,h(a-1,b,c,d)]+size[v])等四种转移
其中v=map[u,i],size[v]表示trie上到v节点路径出现次数之和
边界条件dp[1,h(0,0,0,0)]=1
- var map:array[..,..]of longint;
- q,a,size,fa:array[..]of longint;
- hash:array[..,..,..,..]of longint;
- dp:array[..,..]of longint;
- ch:string;
- n,cnt,i,j,k,x,t,y,ans,len,s,cas,a1,c1,g1,t1,u,s1,v,s2,num:longint;
- flag:boolean;
- function min(x,y:longint):longint;
- begin
- if x<y then exit(x);
- exit(y);
- end;
- function max(x,y:longint):longint;
- begin
- if x>y then exit(x);
- exit(y);
- end;
- procedure build;
- var i,u:longint;
- begin
- u:=;
- for i:= to len do
- begin
- if map[u,a[i]]= then
- begin
- inc(cnt); map[u,a[i]]:=cnt;
- end;
- u:=map[u,a[i]];
- end;
- inc(size[u]);
- end;
- procedure acauto;
- var t,w,i,p,son,u:longint;
- begin
- t:=; w:=; q[]:=;
- while t<w do
- begin
- inc(t); u:=q[t];
- size[u]:=size[u]+size[fa[u]];
- for i:= to do
- if map[u,i]> then
- begin
- son:=map[u,i];
- p:=fa[u];
- if u= then fa[son]:=
- else fa[son]:=map[p,i];
- inc(w); q[w]:=son;
- end
- else
- begin
- p:=fa[u];
- if u= then map[u,i]:=
- else map[u,i]:=map[p,i];
- end;
- end;
- end;
- begin
- assign(input,'hdoj3341.in'); reset(input);
- assign(output,'hdoj3341.out'); rewrite(output);
- while not eof do
- begin
- readln(n);
- if n= then break;
- inc(cas);
- for i:= to cnt do
- begin
- size[i]:=; fa[i]:=;
- end;
- for i:= to cnt do
- for j:= to do map[i,j]:=;
- for i:= to a1 do
- for j:= to c1 do
- for k:= to g1 do
- for x:= to t1 do hash[i,j,k,x]:=;
- cnt:=;
- for i:= to n do
- begin
- readln(ch);
- len:=length(ch);
- for j:= to len do
- begin
- case ch[j] of
- 'A':a[j]:=;
- 'C':a[j]:=;
- 'G':a[j]:=;
- 'T':a[j]:=;
- end;
- end;
- build;
- end;
- acauto;
- readln(ch);
- len:=length(ch); a1:=; c1:=; g1:=; t1:=;
- for i:= to len do
- begin
- case ch[i] of
- 'A':inc(a1);
- 'C':inc(c1);
- 'G':inc(g1);
- 'T':inc(t1);
- end;
- end;
- num:=;
- for i:= to a1 do
- for j:= to c1 do
- for k:= to g1 do
- for x:= to t1 do
- begin
- inc(num); hash[i,j,k,x]:=num;
- end;
- for i:= to cnt do
- for j:= to a1 do
- for k:= to c1 do
- for x:= to g1 do
- for y:= to t1 do dp[i,hash[j,k,x,y]]:=-;
- dp[,hash[,,,]]:=;
- ans:=;
- for i:= to a1 do
- for j:= to c1 do
- for k:= to g1 do
- for x:= to c1 do
- begin
- if i+j+k+x= then continue;
- s1:=hash[i,j,k,x];
- for u:= to cnt do
- for t:= to do
- begin
- v:=map[u,t];
- s2:=;
- if (t=)and(i>=) then s2:=hash[i-,j,k,x]
- else if (t=)and(j>=) then s2:=hash[i,j-,k,x]
- else if (t=)and(k>=) then s2:=hash[i,j,k-,x]
- else if (t=)and(x>=) then s2:=hash[i,j,k,x-];
- if s2= then continue;
- if dp[u,s2]=- then continue;
- dp[v,s1]:=max(dp[v,s1],dp[u,s2]+size[v]);
- ans:=max(ans,dp[v,s1]);
- end;
- end;
- writeln('Case ',cas,': ',ans);
- end;
- close(input);
- close(output);
- end.
UPD(2018.10.27):C++重写 果然C++常数小
- #include<cstdio>
- #include<cstring>
- #include<string>
- #include<cmath>
- #include<iostream>
- #include<algorithm>
- #include<map>
- #include<set>
- #include<queue>
- #include<vector>
- using namespace std;
- typedef long long ll;
- typedef unsigned int uint;
- typedef unsigned long long ull;
- typedef pair<int,int> PII;
- typedef vector<int> VI;
- #define fi first
- #define se second
- #define MP make_pair
- #define N 610
- #define M 7010
- #define eps 1e-8
- #define pi acos(-1)
- #define oo 1e9
- #define MOD 10007
- int nxt[N][],q[N],size[N],fa[N],num[][][][],dp[N][],
- A,C,G,T,len,cnt;
- char b[M],ch[M];
- void build()
- {
- int u=;
- for(int i=;i<=len;i++)
- {
- int t;
- if(b[i]=='A') t=;
- if(b[i]=='C') t=;
- if(b[i]=='G') t=;
- if(b[i]=='T') t=;
- if(!nxt[u][t]) nxt[u][t]=++cnt;
- u=nxt[u][t];
- }
- size[u]++;
- }
- void acauto()
- {
- int t=; int w=; q[]=;
- while(t<w)
- {
- int u=q[++t];
- size[u]+=size[fa[u]];
- for(int i=;i<=;i++)
- {
- if(nxt[u][i])
- {
- int son=nxt[u][i];
- int p=fa[u];
- if(u==) fa[son]=;
- else fa[son]=nxt[p][i];
- q[++w]=son;
- }
- else
- {
- int p=fa[u];
- if(u==) nxt[u][i]=;
- else nxt[u][i]=nxt[p][i];
- }
- }
- }
- }
- int main()
- {
- //freopen("hdoj3341.in","r",stdin);
- //freopen("hdoj3341.out","w",stdout);
- int n;
- int cas=;
- A=C=G=T=cnt=;
- while(scanf("%d",&n)!=EOF)
- {
- if(n==) break;
- cas++;
- for(int i=;i<=cnt;i++) size[i]=fa[i]=;
- for(int i=;i<=cnt;i++)
- for(int j=;j<=;j++) nxt[i][j]=;
- for(int i=;i<=A;i++)
- for(int j=;j<=C;j++)
- for(int k=;k<=G;k++)
- for(int x=;x<=T;x++) num[i][j][k][x]=;
- cnt=;
- for(int i=;i<=n;i++){scanf("%s",b+); len=strlen(b+); build();}
- acauto();
- scanf("%s",ch+);
- len=strlen(ch+);
- A=C=G=T=;
- for(int i=;i<=len;i++)
- {
- if(ch[i]=='A') A++;
- if(ch[i]=='C') C++;
- if(ch[i]=='G') G++;
- if(ch[i]=='T') T++;
- }
- int s=;
- for(int i=;i<=A;i++)
- for(int j=;j<=C;j++)
- for(int k=;k<=G;k++)
- for(int x=;x<=T;x++) num[i][j][k][x]=++s;
- for(int i=;i<=cnt;i++)
- for(int j=;j<=A;j++)
- for(int k=;k<=C;k++)
- for(int x=;x<=G;x++)
- for(int y=;y<=T;y++) dp[i][num[j][k][x][y]]=-;
- dp[][num[][][][]]=;
- int ans=;
- for(int i=;i<=A;i++)
- for(int j=;j<=C;j++)
- for(int k=;k<=G;k++)
- for(int x=;x<=T;x++)
- {
- if(i+j+k+x==) continue;
- int s1=num[i][j][k][x];
- for(int u=;u<=cnt;u++)
- for(int t=;t<=;t++)
- {
- int v=nxt[u][t];
- int s2=;
- if(t==&&i>=) s2=num[i-][j][k][x];
- if(t==&&j>=) s2=num[i][j-][k][x];
- if(t==&&k>=) s2=num[i][j][k-][x];
- if(t==&&x>=) s2=num[i][j][k][x-];
- if(s2==||dp[u][s2]==-) continue;
- dp[v][s1]=max(dp[v][s1],dp[u][s2]+size[v]);
- ans=max(ans,dp[v][s1]);
- }
- }
- printf("Case %d: %d\n",cas,ans);
- }
- return ;
- }
【HDOJ3341】Lost's revenge(AC自动机,DP)的更多相关文章
- HDU 3341 Lost's revenge AC自动机+dp
Lost's revenge Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)T ...
- HDU3341 Lost's revenge(AC自动机&&dp)
一看到ACGT就会想起AC自动机上的dp,这种奇怪的联想可能是源于某道叫DNA什么的题的. 题意,给你很多个长度不大于10的小串,小串最多有50个,然后有一个长度<40的串,然后让你将这个这个长 ...
- hdu3341Lost's revenge(ac自动机+dp)
链接 类似的dp省赛时就做过了,不过这题卡内存,需要把当前状态hash一下,可以按进制来算出当前的状态,因为所有的状态数是不会超过10*10*10*10的,所以完全可以把这些存下来. 刚开始把trie ...
- HDU-3341-Lost's revenge(AC自动机, DP, 压缩)
链接: https://vjudge.net/problem/HDU-3341 题意: Lost and AekdyCoin are friends. They always play "n ...
- 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 ...
随机推荐
- Join方法,yield方法,线程的优先级
- Windows远程桌面连接复制文件失败或非常慢
环境搭建过程中经常会遇到需要将文件从本机传到云服务器或者企业内部服务器上的场景,此时如果文件过大的话要传个半天或者直接告诉你复制失败,让人好生无奈 ~ ~. windows环境下,可以将本地磁盘映 ...
- 简单工厂模式-Java篇
简单工厂模式就是考虑如何实例化对象的问题,就是说到底要实例化谁,将来会不会增加实例化对象,比如计算器类中增加开根元素,应该考虑用一个单独的类来创造实例的过程,这就是工厂.下面将利用计算器类举例,解释简 ...
- Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置文件
导航 目 录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:新版本说明 下一篇:Farseer.net轻量级ORM开源框架 ...
- 关于Farseer.net轻量级ORM开源框架 V1.0 概念版本开发的消息
V0.2版的开源距离今天(05年03月)已有近3年的时间.可以说这个版本已经有点落伍的感觉了,呵呵. V0.2版至今一直处于BUG的修复及一些细小功能的增加,所以版本号上一直没有变化. 其实在这1.2 ...
- dd - 转换和拷贝文件
摘要 dd [--help] [--version] [if=file] [of=file] [ibs=bytes] [obs=bytes] [bs=bytes] [cbs=bytes] [skip= ...
- 机器学习_决策树Python代码详解
决策树优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据: 决策树缺点:可能会产生过度匹配问题. 决策树的一般步骤: (1)代码中def 1,计算给定数据集的香农熵: ...
- c++ include
#include <>与#include " "区别 如果头文件名在<>中,就会被认为是标准头文件.编译器会在预定义的位置查找该头文件,如果是"& ...
- 德尔福 XE5 安卓调试
https://stackoverflow.com/questions/2604727/how-can-i-connect-to-android-with-adb-over-tcp?page=2&am ...
- Java 调用存储过程 返回结果集
这里使用Oracle数据库的thin连接. 下面是存储过程SQL 1 createorreplaceprocedure proc3(stid in student.stuid%type, stname ...