APIO 2008 脱氧核糖核酸(dna) 解题报告

题目与数据移步APIO官方网站:http://www.apio.olympiad.org/

首先我对ACGT分别标号为1234,方便后面计算。于是把DNA储存为一个st串,0表示N.

我们对他的所谓“范式-j”做一下深入剖析,发现,“范式-j”无非是符合st[ x ] > st [ x + 1 ]的x的个数要小于j.

我们可以设计状态f [ i , be , ik ]表示st [ i ] .. st [ m ]中,st[ i ]是be,里面符合st[ x ] > st [ x + 1 ]的x的个数为ik。

然后

2{ZG3]DGU8PR2S[9@K%9TX1

也便是st [ i ] .. st [ m ]中,st[ i ]是be,的范式-ik的个数。

可以得到状态转移方程:

1) 若st [ i ] = be或者 st [ i ] = 0那么,

image

2) 否则,

f [ i , be , ik ] = 0

于是我们可以在O ( m * 4^2 * k ) 的时间复杂度内算出所有的f和sum。

然后我们从头往后扫,对第i位置个位置,从1到4枚举be, 若发现sum[ i , be , K ] < R, 就表明在这个位置填这种核苷酸不能达到结果。所以就 r := r – sum[ i , be, k ] , 若be小于i-1处填的核苷酸,那么便 k := k – 1 。 如果sum[ i , be , K ] >= R , 就表明这个位置应该填be了,便去处理第i + 1个位置了。

我的程序:

{
ID: sinya1
PROG: dna
LANG: PASCAL
}

uses math;

const
  code:array[‘A’..’T’]of longint=(1,0,2,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,4);
  decode:array[1..4]of char=(‘A’,’C’,’G’,’T’);
  maxm=50000;
  maxl=maxm;
  maxk=9;

var
  m,k,i,be,next,ik,up,down:longint;
  st:array[0..maxm]of longint;
  ch:char;
  f,sum:array[1..maxm+1,1..4,0..maxk]of int64;
  r:int64;

procedure init;begin
  readln(m,k,r);dec(k);
  for i:=1 to m do begin
    read(ch);st[i]:=code[ch];
  end;
  st[0]:=1;
end;

procedure dp;begin
  fillchar(f,sizeof(f),0);
  fillchar(sum,sizeof(sum),0);
  f[m+1,4,0]:=1;
  for i:=m downto 1 do begin
    if st[i]>0 then begin
      up:=st[i];down:=up;
    end else begin
      up:=4;down:=1;
    end;
    for be:=down to up do begin
      for ik:=0 to k do
        for next:=be to 4 do
          f[i,be,ik]:=f[i,be,ik]+f[i+1,next,ik];
      for ik:=1 to k do
        for next:=1 to be-1 do
          f[i,be,ik]:=f[i,be,ik]+f[i+1,next,ik-1];
      sum[i,be,0]:=f[i,be,0];
      for ik:=1 to k do
        sum[i,be,ik]:=sum[i,be,ik-1]+f[i,be,ik];
    end;
  end;
end;

procedure find;begin
  for i:=1 to m do begin
    dec(k);
    for be:=1 to 4 do begin
      if be=st[i-1] then inc(k);
      if sum[i,be,k]>=r then break
      else r:=r-sum[i,be,k];
    end;
    st[i]:=be;
    write(decode[st[i]]);
  end;
  writeln;
end;

begin
  assign(input,’dna.in’);reset(input);
  assign(output,’dna.sol’);rewrite(output);

  init;
  dp;
  find;

  close(input);close(output);
end.

文章已创建 223

2 个评论 在 “APIO 2008 脱氧核糖核酸(dna) 解题报告

  1. dna那导题的数据特别大,会超过int64

    需要
    if f[a,b,c]>r then f[a,b,c]:=r+1
    因为f[a,b,c]不可能被用到了

    你的程序好像会超界吧??

  2. 您会发现,这个范式k是一个巨大的约束条件!可以使所有符合的情况降为多项式级别。

    而且!最根本的是!题目明确告诉你所有符合范式k的总数不超过10^18,也告诉你int64存得下 = =|||

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部