zoukankan      html  css  js  c++  java
  • 【POJ3691】DNA repair(AC自动机,DP)

    题意:

    生物课上我们学到,DNA序列中只有A, C, T和G四种片段。

    经科学发现,DNA序列中,包含某些片段会产生不好的基因,如片段”ATC”是不好片段,则”AGATCC”, “CATCAA”, “ATCATC”都是不好的DNA序列,这些不好片段我们可以称为病毒片段

    现在已知m个病毒片段, 然后给定一个DNA串,问如果使用最少的修改(将DNA中的某个字母,变为其他字母,比如A变T,但变的字母也只能是”ACTG”),使得这个DNA串不包含病毒片段

    【数据规模和约定】

     

    1<=m<=50  病毒片段长度不超过20,只含A,T,C,G字母

     

    DNA串长度不超过1000, 只含A, T, C, G字母

     

    思路:AC自动机上的DP

    判断是否病毒部分与上一道相同

    设dp[i,j]为在原串上前i个字母上改,现在在自动机上j号节点的最小值

    [ dp[i,x]=minegin{cases} dp[i-1,j] (k=ch[i])\dp[i-1,j]+1 (k<>ch[i])end{cases} ]

    其中x为j号节点走字母k之后所到达的节点号,要求j号节点为合法节点

    答案即为[ min(dp[len,i]) (i为合法节点) ]

     1 const s:array[1..4]of char=('A','C','G','T');
     2       oo=500000000;
     3 var map:array[1..1100,'A'..'T']of longint;
     4     dp:array[0..1100,0..1000]of longint;
     5     b,f:array[0..1100]of longint;
     6     q:array[1..200000]of longint;
     7     n,tot,i,j,k,d,ans,num,p,cas:longint;
     8     ch:ansistring;
     9 
    10 
    11 procedure build;
    12 var i,d,u:longint;
    13 begin
    14  u:=1; d:=length(ch);
    15  for i:=1 to d do
    16  begin
    17   if map[u,ch[i]]=0 then begin inc(num); map[u,ch[i]]:=num; end;
    18   u:=map[u,ch[i]];
    19  end;
    20  b[u]:=1;
    21 end;
    22 
    23 procedure acauto;
    24 var t,w,u,p,son,i:longint;
    25 begin
    26  t:=0; w:=1; q[1]:=1;
    27  while t<w do
    28  begin
    29   inc(t); u:=q[t];
    30   if b[f[u]]=1 then b[u]:=1;
    31   for i:=1 to 4 do
    32    if map[u,s[i]]>0 then
    33    begin
    34     son:=map[u,s[i]];
    35     p:=f[u];
    36     if u=1 then f[son]:=1
    37      else f[son]:=map[p,s[i]];
    38     inc(w); q[w]:=son;
    39    end
    40     else
    41     begin
    42      p:=f[u];
    43      if u=1 then map[u,s[i]]:=1
    44       else map[u,s[i]]:=map[p,s[i]];
    45     end;
    46  end;
    47 end;
    48 
    49 function min(x,y:longint):longint;
    50 begin
    51  if x<y then exit(x);
    52  exit(y);
    53 end;
    54 
    55 begin
    56  assign(input,'poj3691.in'); reset(input);
    57  assign(output,'poj3691.out'); rewrite(output);
    58  while not eof do
    59  begin
    60   fillchar(f,sizeof(f),0);
    61   fillchar(b,sizeof(b),0);
    62   fillchar(dp,sizeof(dp),$1f);
    63   for i:=1 to num do
    64    for j:=1 to 4 do map[i,s[j]]:=0;
    65   readln(n);
    66   if n=0 then break;
    67   num:=1; inc(cas);
    68   for i:=1 to n do
    69   begin
    70    readln(ch);
    71    build;
    72   end;
    73   acauto;
    74   readln(ch);
    75   dp[0,1]:=0; d:=length(ch);
    76   for i:=1 to d do
    77    for j:=1 to num do
    78     if (b[j]=0)and(dp[i-1,j]<oo) then
    79      for k:=1 to 4 do
    80      begin
    81       p:=map[j,s[k]];
    82       if b[p]=0 then
    83       begin
    84        if ch[i]=s[k] then dp[i,p]:=min(dp[i,p],dp[i-1,j])
    85         else dp[i,p]:=min(dp[i,p],dp[i-1,j]+1);
    86       end;
    87      end;
    88   ans:=oo;
    89   for i:=1 to num do
    90    if b[i]=0 then ans:=min(ans,dp[d,i]);
    91   write('Case ',cas,': ');
    92   if ans<oo then writeln(ans)
    93    else writeln(-1);
    94  end;
    95  close(input);
    96  close(output);
    97 end.

     

     

     

  • 相关阅读:
    定时任务
    ---Ubuntu 连接手机tethering
    ---thunar 文件浏览器的使用!
    ---recovery ui 修改
    ---wordpress 升级遇到的问题!
    ---BD PROCHOT
    ---安装/修复Ubuntu/Ach Linux efi 启动 !!!(包括双系统启动)
    ---sgdisk 分区表
    --- cache PV 丢失或损坏 怎么办
    ---lvm2分区修复问题!
  • 原文地址:https://www.cnblogs.com/myx12345/p/6238155.html
Copyright © 2011-2022 走看看