codevs1050 棋盘染色 2

6 篇文章 0 订阅
1 篇文章 0 订阅

原题网址:http://codevs.cn/problem/1050/
这里写图片描述

插头dp板子题
论文链接:http://wenku.baidu.com/link?url=ppnlF-_UyXkM0fWq4lByxGxjd4K67RpRywuLSgWUNwqAqsT69Hx3plGfBeaUR7pW55_CO5PaxfpH3mbRIzJm2XdNvFRepBwUk5y88_gEH1u

很早理论上就会了,但一直由于码力,之前尝试了一下,一直调不出来。这次运气好写出来了,整理一下。

首先一行五格联通块数最多为3,所以0 1 2 3都可以填入,每行有4^5=1024种状态,实际上有很多状态都是不合法的,可以打标把合法状态打出来:

var
  a:array[0..5] of longint;
  cnt:longint;
procedure print;
  var
    i:longint;
  begin
    write('(');
    for i:=1 to 4 do
      write(a[i],',');
    writeln(a[5],'),');
    inc(cnt);
  end;
procedure print2;
  begin
    inc(cnt);
    writeln('    detrans[',a[1],'][',a[2],'][',a[3],'][',a[4],'][',a[5],']:=',cnt,';');
  end;
function check:boolean;
  var
    exs:array[0..3] of boolean;
    i,j:longint;
  begin
    for i:=1 to 4 do
      if (a[i]<>0)and(a[i+1]<>0)and(a[i]<>a[i+1])
        then exit(false);
    fillchar(exs,sizeof(exs),false);
    for i:=1 to 5 do
      begin
        if (a[i]=0) then continue;
        for j:=1 to a[i]-1 do
          if (not exs[j])
            then exit(false);
        exs[a[i]]:=true;
      end;
    exit(true);
  end;
procedure dfs(dep:longint);
  var
    i:longint;
  begin
    if dep>5 then
      begin
        if check then print2;
        exit;
      end;
    for i:=0 to 3 do
      begin
        a[dep]:=i;
        dfs(dep+1);
      end;
  end;
begin
  assign(output,'form.out');rewrite(output);
  dfs(1);
  writeln(cnt);
  close(output);
end.

由打出的状态我写了cv1050 1.0.0:

{$mode objfpc}
const
  cost:array[0..31] of longint=(0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5);
  trans:array[1..51,1..5] of longint=(
    (0,0,0,0,0),(0,0,0,0,1),(0,0,0,1,0),(0,0,0,1,1),(0,0,1,0,0),
    (0,0,1,0,1),(0,0,1,0,2),(0,0,1,1,0),(0,0,1,1,1),(0,1,0,0,0),
    (0,1,0,0,1),(0,1,0,0,2),(0,1,0,1,0),(0,1,0,1,1),(0,1,0,2,0),
    (0,1,0,2,2),(0,1,1,0,0),(0,1,1,0,1),(0,1,1,0,2),(0,1,1,1,0),
    (0,1,1,1,1),(1,0,0,0,0),(1,0,0,0,1),(1,0,0,0,2),(1,0,0,1,0),
    (1,0,0,1,1),(1,0,0,2,0),(1,0,0,2,2),(1,0,1,0,0),(1,0,1,0,1),
    (1,0,1,0,2),(1,0,1,1,0),(1,0,1,1,1),(1,0,2,0,0),(1,0,2,0,1),
    (1,0,2,0,2),(1,0,2,0,3),(1,0,2,2,0),(1,0,2,2,2),(1,1,0,0,0),
    (1,1,0,0,1),(1,1,0,0,2),(1,1,0,1,0),(1,1,0,1,1),(1,1,0,2,0),
    (1,1,0,2,2),(1,1,1,0,0),(1,1,1,0,1),(1,1,1,0,2),(1,1,1,1,0),
    (1,1,1,1,1));
  INF=maxlongint>>1;
var
  f:array[0..101,1..51] of longint;
  detrans:array[0..3,0..3,0..3,0..3,0..3] of longint;
  status:array[0..101] of longint;
  n,i,j,left,now,new,mx,ans,line:longint;
procedure init;
  begin
    detrans[0][0][0][0][0]:=1;
    detrans[0][0][0][0][1]:=2;
    detrans[0][0][0][1][0]:=3;
    detrans[0][0][0][1][1]:=4;
    detrans[0][0][1][0][0]:=5;
    detrans[0][0][1][0][1]:=6;
    detrans[0][0][1][0][2]:=7;
    detrans[0][0][1][1][0]:=8;
    detrans[0][0][1][1][1]:=9;
    detrans[0][1][0][0][0]:=10;
    detrans[0][1][0][0][1]:=11;
    detrans[0][1][0][0][2]:=12;
    detrans[0][1][0][1][0]:=13;
    detrans[0][1][0][1][1]:=14;
    detrans[0][1][0][2][0]:=15;
    detrans[0][1][0][2][2]:=16;
    detrans[0][1][1][0][0]:=17;
    detrans[0][1][1][0][1]:=18;
    detrans[0][1][1][0][2]:=19;
    detrans[0][1][1][1][0]:=20;
    detrans[0][1][1][1][1]:=21;
    detrans[1][0][0][0][0]:=22;
    detrans[1][0][0][0][1]:=23;
    detrans[1][0][0][0][2]:=24;
    detrans[1][0][0][1][0]:=25;
    detrans[1][0][0][1][1]:=26;
    detrans[1][0][0][2][0]:=27;
    detrans[1][0][0][2][2]:=28;
    detrans[1][0][1][0][0]:=29;
    detrans[1][0][1][0][1]:=30;
    detrans[1][0][1][0][2]:=31;
    detrans[1][0][1][1][0]:=32;
    detrans[1][0][1][1][1]:=33;
    detrans[1][0][2][0][0]:=34;
    detrans[1][0][2][0][1]:=35;
    detrans[1][0][2][0][2]:=36;
    detrans[1][0][2][0][3]:=37;
    detrans[1][0][2][2][0]:=38;
    detrans[1][0][2][2][2]:=39;
    detrans[1][1][0][0][0]:=40;
    detrans[1][1][0][0][1]:=41;
    detrans[1][1][0][0][2]:=42;
    detrans[1][1][0][1][0]:=43;
    detrans[1][1][0][1][1]:=44;
    detrans[1][1][0][2][0]:=45;
    detrans[1][1][0][2][2]:=46;
    detrans[1][1][1][0][0]:=47;
    detrans[1][1][1][0][1]:=48;
    detrans[1][1][1][0][2]:=49;
    detrans[1][1][1][1][0]:=50;
    detrans[1][1][1][1][1]:=51;
  end;
procedure inputt;
  var
    st:string;
    i,p,s:longint;
  begin
    readln(n);
    for i:=1 to n do
      begin
        readln(st);s:=0;
        for j:=5 downto 1 do
          s:=s << 1 + ord(st[j]='1');
        status[i]:=s;
      end;
    while status[n]=0 do dec(n);
    p:=0;while (p+1<=n)and(status[p+1]=0) do inc(p);
    for i:=p+1 to n do status[i-p]:=status[i];
    dec(n,p);//把首末的全0行删掉,否则会把那些行全连起来,答案变劣
  end;
function max(a,b:longint):longint;
  begin if (a>b) then exit(a) else exit(b); end;
function min(a,b:longint):longint;
  begin if (a< b) then exit(a) else exit(b); end;
function translate(last,now,outi:longint):longint;
  var
    t1,t2,t3,ref:array[0..6] of longint;
    exs:array[0..3] of boolean;
    i,p,cnt:longint;
    flag:boolean;
  begin
    for i:=1 to 5 do
      begin
        t1[i]:=now and 1;
        now:=now >> 1;
      end;//t1转换成01取或不取
    fillchar(exs,sizeof(exs),false);
    exs[0]:=true;
    for i:=1 to 5 do
      if (t1[i]=1)
        then exs[trans[last][i]]:=true;
    for i:=1 to 5 do
      if (not exs[trans[last][i]])
        then exit(-1);//如果上一行有联通块断子绝孙(没有接下来)是不合法的
    fillchar(ref,sizeof(ref),0);
    fillchar(t2,sizeof(t2),0);
    cnt:=0;
    for i:=1 to 5 do
      if (trans[last][i]>0)and(t1[i]=1) then
        if (t2[i]=0)//t2记录初步标号
          then
            begin
              if (ref[trans[last][i]]=0)
                then begin inc(cnt);ref[trans[last][i]]:=cnt;end;
              t2[i]:=ref[trans[last][i]];
              p:=i;
              while (p<5)and(t1[p+1]=1) do
                begin
                  inc(p);
                  t2[p]:=ref[trans[last][i]];
                end;
              p:=i;
              while (p>1)and(t1[p-1]=1) do
                begin
                  dec(p);
                  t2[p]:=ref[trans[last][i]];
                end;//上一行映射到下一行
            end
          else ref[trans[last][i]]:=t2[i];//下一行的标号反过来可以映射到上一行
    if (outi>0) then
      begin
        flag:=false;
        for i:=1 to 5 do
          flag:=flag or (t2[i]>0);
        if (not flag) then exit(-1);
      end;//如果不是第0行,不能一个都不传下来
    for i:=1 to 5 do
      if (t1[i]=1)and(t2[i]=0) then
        begin
          inc(cnt);p:=i;
          repeat
            t2[p]:=cnt;
            inc(p);
          until (p>5)or(t1[p]=0)or(t2[p]<>0);
        end;//给新多出的联通块标号
    for i:=1 to 5 do
      if (t2[i]=cnt)and((t2[i-1]<>0)and(t2[i-1]<>cnt)or(t2[i+1]<>0)and(t2[i+1]<>cnt))
        then exit(-1);//新的联通块不能与旧联通块联通
        fillchar(ref,sizeof(ref),0);
    cnt:=0;
    for i:=1 to 5 do
      if (t2[i]>0)and(ref[t2[i]]=0)
        then begin inc(cnt);ref[t2[i]]:=cnt;end;
    for i:=1 to 5 do
      t3[i]:=ref[t2[i]];//遵循最小标号重新标号
    exit(detrans[t3[1]][t3[2]][t3[3]][t3[4]][t3[5]]);
  end;
begin
  init;
  inputt;
  for i:=0 to n do
    for j:=1 to 51 do
      f[i][j]:=INF;
  f[0][1]:=0;
  for i:=0 to n-1 do
    for j:=1 to 51 do
      begin
        if (f[i][j]=INF) then continue;
        left:=31 xor status[i+1];
        now:=left;
        repeat
          new:=translate(j,status[i+1] or now,i);
          if (new<>-1)
            then f[i+1][new]:=min(f[i+1][new],f[i][j]+cost[now]);
          now:=(now-1) and left;
        until now=0;
        new:=translate(j,status[i+1],i);
        if (new<>-1)
          then f[i+1][new]:=min(f[i+1][new],f[i][j]);
      end;
  ans:=INF;
  for i:=1 to 51 do
    begin
      mx:=0;
      for j:=1 to 5 do
        mx:=max(mx,trans[i][j]);
      if (mx<=1)
        then ans:=min(ans,f[n][i]);
    end;
  writeln(ans);
end.

跑下来要45ms,感觉太慢了,突然发现转移不用在线算,完全可以早早地把转移的表打出来,就是1.5.0版本:

const
  common_transfer:array[1..51,0..31] of longint=(
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,24,12,42,7,37,19,49,4,28,16,46,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,3,27,15,45,8,38,20,50,-1,-1,-1,-1,-1,-1,-1,-1,4,28,16,46,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,3,27,15,45,8,38,20,50,2,24,12,42,7,37,19,49,4,28,16,46,9,39,21,51),
(-1,-1,-1,-1,5,34,17,47,-1,-1,-1,-1,8,38,20,50,-1,-1,-1,-1,7,37,19,49,-1,-1,-1,-1,9,39,21,51),
(-1,-1,-1,-1,5,34,17,47,-1,-1,-1,-1,8,38,20,50,2,24,12,42,6,36,18,48,4,28,16,46,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,7,37,19,49,-1,-1,-1,-1,9,39,21,51),
(-1,-1,-1,-1,5,34,17,47,3,27,15,45,8,38,20,50,-1,-1,-1,-1,7,37,19,49,4,28,16,46,9,39,21,51),
(-1,-1,-1,-1,5,34,17,47,3,27,15,45,8,38,20,50,2,24,12,42,6,36,18,48,4,28,16,46,9,39,21,51),
(-1,-1,10,40,-1,-1,17,47,-1,-1,15,45,-1,-1,20,50,-1,-1,12,42,-1,-1,19,49,-1,-1,16,46,-1,-1,21,51),
(-1,-1,10,40,-1,-1,17,47,-1,-1,15,45,-1,-1,20,50,2,24,11,41,7,37,18,48,4,28,14,44,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,42,-1,-1,19,49,-1,-1,16,46,-1,-1,21,51),
(-1,-1,10,40,-1,-1,17,47,3,27,13,43,8,38,20,50,-1,-1,12,42,-1,-1,19,49,4,28,14,44,9,39,21,51),
(-1,-1,10,40,-1,-1,17,47,3,27,13,43,8,38,20,50,2,24,11,41,7,37,18,48,4,28,14,44,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,45,-1,-1,20,50,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,46,-1,-1,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,45,-1,-1,20,50,-1,-1,12,42,-1,-1,19,49,-1,-1,16,46,-1,-1,21,51),
(-1,-1,10,40,5,34,17,47,-1,-1,15,45,8,38,20,50,-1,-1,12,42,7,37,19,49,-1,-1,16,46,9,39,21,51),
(-1,-1,10,40,5,34,17,47,-1,-1,15,45,8,38,20,50,2,24,11,41,6,36,18,48,4,28,14,44,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,42,7,37,19,49,-1,-1,16,46,9,39,21,51),
(-1,-1,10,40,5,34,17,47,3,27,13,43,8,38,20,50,-1,-1,12,42,7,37,19,49,4,28,14,44,9,39,21,51),
(-1,-1,10,40,5,34,17,47,3,27,13,43,8,38,20,50,2,24,11,41,6,36,18,48,4,28,14,44,9,39,21,51),
(-1,22,-1,40,-1,34,-1,47,-1,27,-1,45,-1,38,-1,50,-1,24,-1,42,-1,37,-1,49,-1,28,-1,46,-1,39,-1,51),
(-1,22,-1,40,-1,34,-1,47,-1,27,-1,45,-1,38,-1,50,2,23,12,41,7,35,19,48,4,26,16,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,-1,42,-1,37,-1,49,-1,28,-1,46,-1,39,-1,51),
(-1,22,-1,40,-1,34,-1,47,3,25,15,43,8,32,20,50,-1,24,-1,42,-1,37,-1,49,4,26,16,44,9,33,21,51),
(-1,22,-1,40,-1,34,-1,47,3,25,15,43,8,32,20,50,2,23,12,41,7,35,19,48,4,26,16,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,27,-1,45,-1,38,-1,50,-1,-1,-1,-1,-1,-1,-1,-1,-1,28,-1,46,-1,39,-1,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,27,-1,45,-1,38,-1,50,-1,24,-1,42,-1,37,-1,49,-1,28,-1,46,-1,39,-1,51),
(-1,22,-1,40,5,29,17,47,-1,27,-1,45,8,32,20,50,-1,24,-1,42,7,31,19,49,-1,28,-1,46,9,33,21,51),
(-1,22,-1,40,5,29,17,47,-1,27,-1,45,8,32,20,50,2,23,12,41,6,30,18,48,4,26,16,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,-1,42,7,31,19,49,-1,28,-1,46,9,33,21,51),
(-1,22,-1,40,5,29,17,47,3,25,15,43,8,32,20,50,-1,24,-1,42,7,31,19,49,4,26,16,44,9,33,21,51),
(-1,22,-1,40,5,29,17,47,3,25,15,43,8,32,20,50,2,23,12,41,6,30,18,48,4,26,16,44,9,33,21,51),
(-1,-1,-1,-1,-1,34,-1,47,-1,-1,-1,-1,-1,38,-1,50,-1,-1,-1,-1,-1,37,-1,49,-1,-1,-1,-1,-1,39,-1,51),
(-1,-1,-1,-1,-1,34,-1,47,-1,-1,-1,-1,-1,38,-1,50,-1,-1,-1,-1,7,35,19,48,-1,-1,-1,-1,9,39,21,51),
(-1,-1,-1,-1,-1,34,-1,47,-1,-1,-1,-1,-1,38,-1,50,-1,24,-1,42,-1,36,-1,48,-1,28,-1,46,-1,39,-1,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,37,-1,49,-1,-1,-1,-1,-1,39,-1,51),
(-1,-1,-1,-1,-1,34,-1,47,-1,27,-1,45,-1,38,-1,50,-1,-1,-1,-1,-1,37,-1,49,-1,28,-1,46,-1,39,-1,51),
(-1,-1,-1,-1,-1,34,-1,47,-1,27,-1,45,-1,38,-1,50,-1,24,-1,42,-1,36,-1,48,-1,28,-1,46,-1,39,-1,51),
(-1,22,10,40,-1,34,17,47,-1,27,15,45,-1,38,20,50,-1,24,12,42,-1,37,19,49,-1,28,16,46,-1,39,21,51),
(-1,22,10,40,-1,34,17,47,-1,27,15,45,-1,38,20,50,2,23,11,41,7,35,18,48,4,26,14,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,12,42,-1,37,19,49,-1,28,16,46,-1,39,21,51),
(-1,22,10,40,-1,34,17,47,3,25,13,43,8,32,20,50,-1,24,12,42,-1,37,19,49,4,26,14,44,9,33,21,51),
(-1,22,10,40,-1,34,17,47,3,25,13,43,8,32,20,50,2,23,11,41,7,35,18,48,4,26,14,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,27,15,45,-1,38,20,50,-1,-1,-1,-1,-1,-1,-1,-1,-1,28,16,46,-1,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,27,15,45,-1,38,20,50,-1,24,12,42,-1,37,19,49,-1,28,16,46,-1,39,21,51),
(-1,22,10,40,5,29,17,47,-1,27,15,45,8,32,20,50,-1,24,12,42,7,31,19,49,-1,28,16,46,9,33,21,51),
(-1,22,10,40,5,29,17,47,-1,27,15,45,8,32,20,50,2,23,11,41,6,30,18,48,4,26,14,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,12,42,7,31,19,49,-1,28,16,46,9,33,21,51),
(-1,22,10,40,5,29,17,47,3,25,13,43,8,32,20,50,-1,24,12,42,7,31,19,49,4,26,14,44,9,33,21,51),
(-1,22,10,40,5,29,17,47,3,25,13,43,8,32,20,50,2,23,11,41,6,30,18,48,4,26,14,44,9,33,21,51));
  first_transfer:array[1..51,0..31] of longint=(
(1,22,10,40,5,34,17,47,3,27,15,45,8,38,20,50,2,24,12,42,7,37,19,49,4,28,16,46,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,24,12,42,7,37,19,49,4,28,16,46,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,3,27,15,45,8,38,20,50,-1,-1,-1,-1,-1,-1,-1,-1,4,28,16,46,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,3,27,15,45,8,38,20,50,2,24,12,42,7,37,19,49,4,28,16,46,9,39,21,51),
(-1,-1,-1,-1,5,34,17,47,-1,-1,-1,-1,8,38,20,50,-1,-1,-1,-1,7,37,19,49,-1,-1,-1,-1,9,39,21,51),
(-1,-1,-1,-1,5,34,17,47,-1,-1,-1,-1,8,38,20,50,2,24,12,42,6,36,18,48,4,28,16,46,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,7,37,19,49,-1,-1,-1,-1,9,39,21,51),
(-1,-1,-1,-1,5,34,17,47,3,27,15,45,8,38,20,50,-1,-1,-1,-1,7,37,19,49,4,28,16,46,9,39,21,51),
(-1,-1,-1,-1,5,34,17,47,3,27,15,45,8,38,20,50,2,24,12,42,6,36,18,48,4,28,16,46,9,39,21,51),
(-1,-1,10,40,-1,-1,17,47,-1,-1,15,45,-1,-1,20,50,-1,-1,12,42,-1,-1,19,49,-1,-1,16,46,-1,-1,21,51),
(-1,-1,10,40,-1,-1,17,47,-1,-1,15,45,-1,-1,20,50,2,24,11,41,7,37,18,48,4,28,14,44,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,42,-1,-1,19,49,-1,-1,16,46,-1,-1,21,51),
(-1,-1,10,40,-1,-1,17,47,3,27,13,43,8,38,20,50,-1,-1,12,42,-1,-1,19,49,4,28,14,44,9,39,21,51),
(-1,-1,10,40,-1,-1,17,47,3,27,13,43,8,38,20,50,2,24,11,41,7,37,18,48,4,28,14,44,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,45,-1,-1,20,50,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,46,-1,-1,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,45,-1,-1,20,50,-1,-1,12,42,-1,-1,19,49,-1,-1,16,46,-1,-1,21,51),
(-1,-1,10,40,5,34,17,47,-1,-1,15,45,8,38,20,50,-1,-1,12,42,7,37,19,49,-1,-1,16,46,9,39,21,51),
(-1,-1,10,40,5,34,17,47,-1,-1,15,45,8,38,20,50,2,24,11,41,6,36,18,48,4,28,14,44,9,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,42,7,37,19,49,-1,-1,16,46,9,39,21,51),
(-1,-1,10,40,5,34,17,47,3,27,13,43,8,38,20,50,-1,-1,12,42,7,37,19,49,4,28,14,44,9,39,21,51),
(-1,-1,10,40,5,34,17,47,3,27,13,43,8,38,20,50,2,24,11,41,6,36,18,48,4,28,14,44,9,39,21,51),
(-1,22,-1,40,-1,34,-1,47,-1,27,-1,45,-1,38,-1,50,-1,24,-1,42,-1,37,-1,49,-1,28,-1,46,-1,39,-1,51),
(-1,22,-1,40,-1,34,-1,47,-1,27,-1,45,-1,38,-1,50,2,23,12,41,7,35,19,48,4,26,16,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,-1,42,-1,37,-1,49,-1,28,-1,46,-1,39,-1,51),
(-1,22,-1,40,-1,34,-1,47,3,25,15,43,8,32,20,50,-1,24,-1,42,-1,37,-1,49,4,26,16,44,9,33,21,51),
(-1,22,-1,40,-1,34,-1,47,3,25,15,43,8,32,20,50,2,23,12,41,7,35,19,48,4,26,16,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,27,-1,45,-1,38,-1,50,-1,-1,-1,-1,-1,-1,-1,-1,-1,28,-1,46,-1,39,-1,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,27,-1,45,-1,38,-1,50,-1,24,-1,42,-1,37,-1,49,-1,28,-1,46,-1,39,-1,51),
(-1,22,-1,40,5,29,17,47,-1,27,-1,45,8,32,20,50,-1,24,-1,42,7,31,19,49,-1,28,-1,46,9,33,21,51),
(-1,22,-1,40,5,29,17,47,-1,27,-1,45,8,32,20,50,2,23,12,41,6,30,18,48,4,26,16,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,-1,42,7,31,19,49,-1,28,-1,46,9,33,21,51),
(-1,22,-1,40,5,29,17,47,3,25,15,43,8,32,20,50,-1,24,-1,42,7,31,19,49,4,26,16,44,9,33,21,51),
(-1,22,-1,40,5,29,17,47,3,25,15,43,8,32,20,50,2,23,12,41,6,30,18,48,4,26,16,44,9,33,21,51),
(-1,-1,-1,-1,-1,34,-1,47,-1,-1,-1,-1,-1,38,-1,50,-1,-1,-1,-1,-1,37,-1,49,-1,-1,-1,-1,-1,39,-1,51),
(-1,-1,-1,-1,-1,34,-1,47,-1,-1,-1,-1,-1,38,-1,50,-1,-1,-1,-1,7,35,19,48,-1,-1,-1,-1,9,39,21,51),
(-1,-1,-1,-1,-1,34,-1,47,-1,-1,-1,-1,-1,38,-1,50,-1,24,-1,42,-1,36,-1,48,-1,28,-1,46,-1,39,-1,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,37,-1,49,-1,-1,-1,-1,-1,39,-1,51),
(-1,-1,-1,-1,-1,34,-1,47,-1,27,-1,45,-1,38,-1,50,-1,-1,-1,-1,-1,37,-1,49,-1,28,-1,46,-1,39,-1,51),
(-1,-1,-1,-1,-1,34,-1,47,-1,27,-1,45,-1,38,-1,50,-1,24,-1,42,-1,36,-1,48,-1,28,-1,46,-1,39,-1,51),
(-1,22,10,40,-1,34,17,47,-1,27,15,45,-1,38,20,50,-1,24,12,42,-1,37,19,49,-1,28,16,46,-1,39,21,51),
(-1,22,10,40,-1,34,17,47,-1,27,15,45,-1,38,20,50,2,23,11,41,7,35,18,48,4,26,14,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,12,42,-1,37,19,49,-1,28,16,46,-1,39,21,51),
(-1,22,10,40,-1,34,17,47,3,25,13,43,8,32,20,50,-1,24,12,42,-1,37,19,49,4,26,14,44,9,33,21,51),
(-1,22,10,40,-1,34,17,47,3,25,13,43,8,32,20,50,2,23,11,41,7,35,18,48,4,26,14,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,27,15,45,-1,38,20,50,-1,-1,-1,-1,-1,-1,-1,-1,-1,28,16,46,-1,39,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,27,15,45,-1,38,20,50,-1,24,12,42,-1,37,19,49,-1,28,16,46,-1,39,21,51),
(-1,22,10,40,5,29,17,47,-1,27,15,45,8,32,20,50,-1,24,12,42,7,31,19,49,-1,28,16,46,9,33,21,51),
(-1,22,10,40,5,29,17,47,-1,27,15,45,8,32,20,50,2,23,11,41,6,30,18,48,4,26,14,44,9,33,21,51),
(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,24,12,42,7,31,19,49,-1,28,16,46,9,33,21,51),
(-1,22,10,40,5,29,17,47,3,25,13,43,8,32,20,50,-1,24,12,42,7,31,19,49,4,26,14,44,9,33,21,51),
(-1,22,10,40,5,29,17,47,3,25,13,43,8,32,20,50,2,23,11,41,6,30,18,48,4,26,14,44,9,33,21,51));
  cost:array[0..31] of longint=(0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5);
  trans:array[1..51,1..5] of longint=(
    (0,0,0,0,0),(0,0,0,0,1),(0,0,0,1,0),(0,0,0,1,1),(0,0,1,0,0),
    (0,0,1,0,1),(0,0,1,0,2),(0,0,1,1,0),(0,0,1,1,1),(0,1,0,0,0),
    (0,1,0,0,1),(0,1,0,0,2),(0,1,0,1,0),(0,1,0,1,1),(0,1,0,2,0),
    (0,1,0,2,2),(0,1,1,0,0),(0,1,1,0,1),(0,1,1,0,2),(0,1,1,1,0),
    (0,1,1,1,1),(1,0,0,0,0),(1,0,0,0,1),(1,0,0,0,2),(1,0,0,1,0),
    (1,0,0,1,1),(1,0,0,2,0),(1,0,0,2,2),(1,0,1,0,0),(1,0,1,0,1),
    (1,0,1,0,2),(1,0,1,1,0),(1,0,1,1,1),(1,0,2,0,0),(1,0,2,0,1),
    (1,0,2,0,2),(1,0,2,0,3),(1,0,2,2,0),(1,0,2,2,2),(1,1,0,0,0),
    (1,1,0,0,1),(1,1,0,0,2),(1,1,0,1,0),(1,1,0,1,1),(1,1,0,2,0),
    (1,1,0,2,2),(1,1,1,0,0),(1,1,1,0,1),(1,1,1,0,2),(1,1,1,1,0),
    (1,1,1,1,1));
  INF=maxlongint>>1;
var
  f:array[0..101,1..51] of longint;
  status:array[0..101] of longint;
  n,i,j,left,now,new,mx,ans:longint;
procedure inputt;
  var
    st:string;
    i,p,s:longint;
  begin
    readln(n);
    for i:=1 to n do
      begin
        readln(st);s:=0;
        for j:=5 downto 1 do
          s:=s << 1 + ord(st[j]='1');
        status[i]:=s;
      end;
    while status[n]=0 do dec(n);
    p:=0;while (p+1<=n)and(status[p+1]=0) do inc(p);
    for i:=p+1 to n do status[i-p]:=status[i];
    dec(n,p);
  end;
function max(a,b:longint):longint;
  begin if (a>b) then exit(a) else exit(b); end;
function min(a,b:longint):longint;
  begin if (a<b) then exit(a) else exit(b); end;
function translate(i,j,k:longint):longint;
  begin
    if (k=0)
      then exit(first_transfer[i][j])
      else exit(common_transfer[i][j]);
  end;
begin
  assign(input,'chess.in');reset(input);
  assign(output,'chess.out');rewrite(output);
  inputt;
  for i:=0 to n do
    for j:=1 to 51 do
      f[i][j]:=INF;
  f[0][1]:=0;
  for i:=0 to n-1 do
    for j:=1 to 51 do
      begin
        if (f[i][j]=INF) then continue;
        left:=31 xor status[i+1];
        now:=left;
        repeat
          new:=translate(j,status[i+1] or now,i);
          if (new<>-1)
            then f[i+1][new]:=min(f[i+1][new],f[i][j]+cost[now]);
          now:=(now-1) and left;
        until now=0;
        new:=translate(j,status[i+1],i);
        if (new<>-1)
          then f[i+1][new]:=min(f[i+1][new],f[i][j]);
      end;
  ans:=INF;
  for i:=1 to 51 do
    begin
      mx:=0;
      for j:=1 to 5 do
        mx:=max(mx,trans[i][j]);
      if (mx<=1)
        then ans:=min(ans,f[n][i]);
    end;
  writeln(ans);
  close(input);close(output);
end.

虽然代码比较长,但跑出来只要5ms,可见插头dp完全可以拿打标来优化冗余状态和预处理转移,从而大大提升速度。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值