1050 棋盘染色 2 - Wikioi


题目描述 Description

    有一个5*N的棋盘,棋盘中的一些格子已经被染成了黑色,你的任务是对最少的格子染色,使得所有的黑色能连成一块。

输入描述 Input Description

    第一行一个整数N(<=100),接下来N行每行一个长度为5的01串,1表示所在格子已经被染成了黑色,0表示所在格子没有被染色。

输出描述 Output Description

    第一行一个整数N(<=100),接下来N行每行一个长度为5的01串,1表示所在格子已经被染成了黑色,0表示所在格子没有被染色。

样例输入 Sample Input

    5
    11100
    11000
    10000
    01111
    11111

样例输出 Sample Output

    1

数据范围及提示 Data Size & Hint

    N(<=100)

写得要吐了,看了Wikioi后面的题解突然有了灵感(看到了时间复杂度和空间复杂度.....)

状压dp,每一行压连通性,因为只有5列,最多有三个互不相交的联通块,所以可以用4进制来表示每一行的状态表示(每一位表示这一格属于第几个联通块)

因为所有的黑色块都必须联通,所以上面的每一个不同的联通块至少有一个要延伸到下面来,这个转移的时候注意一下

对于每一个状态,枚举要下一层涂黑哪些块,然后转移,最后一层黑色都属于同一联通块才能更新答案

 (这个代码其实是错的...下面还有一个)

  1 const
  2     maxn=102;
  3 type
  4     node=record
  5       x,y:longint;
  6     end;
  7     aa=array[0..5]of longint;
  8 var
  9     f:array[0..maxn,0..1204]of longint;
 10     a:array[0..maxn]of longint;
 11     n:longint;
 12 
 13 procedure init;
 14 var
 15     i,j:longint;
 16     s:char;
 17 begin
 18     readln(n);
 19     for i:=1 to n do
 20       begin
 21         for j:=1 to 5 do
 22           begin
 23             read(s);
 24             a[i]:=a[i]<<1+ord(s)-ord('0');
 25           end;
 26         readln;
 27       end;
 28     while n>0 do
 29       begin
 30         if a[n]>0 then break;
 31         dec(n);
 32       end;
 33     if n=0 then
 34     begin
 35       write(0);
 36       halt;
 37     end;
 38 end;
 39 
 40 procedure get(var a:aa);
 41 var
 42     i,j,k,c:longint;
 43 begin
 44     c:=1;
 45     for i:=1 to 3 do
 46       for j:=1 to 5 do
 47         if a[j]=i then
 48         begin
 49           if i=c then inc(c);
 50           k:=j;
 51           while (k>1) and (a[k-1]>0) do
 52             begin
 53               dec(k);
 54               a[k]:=i;
 55             end;
 56           k:=j;
 57           while (k<5) and (a[k+1]>0) do
 58             begin
 59               inc(k);
 60               a[k]:=i;
 61             end;
 62         end;
 63     dec(c);
 64     for i:=1 to 5 do
 65       if a[i]=4 then
 66       begin
 67         if a[i-1]>0 then a[i]:=c
 68         else
 69           begin
 70              inc(c);
 71              a[i]:=c;
 72           end;
 73       end;
 74 end;
 75 
 76 function bit(x:longint):longint;
 77 begin
 78     if x=0 then exit(0);
 79     exit(bit(x-(x and -x))+1);
 80 end;
 81 
 82 var
 83     q:array[0..maxn*1024]of node;
 84 
 85 procedure work;
 86 var
 87     head,tail,i,j,k,ans,save:longint;
 88     s,t:aa;
 89     flag:boolean;
 90 begin
 91     fillchar(f,sizeof(f),1);
 92     t[0]:=0;
 93     ans:=500;
 94     f[0,0]:=0;
 95     q[1].x:=0;
 96     q[1].y:=0;
 97     head:=1;
 98     tail:=1;
 99     while head<=tail do
100       begin
101         save:=q[head].y;
102         for i:=1 to 5 do
103           begin
104             s[i]:=q[head].y and 3;
105             q[head].y:=q[head].y>>2;
106           end;
107         q[head].y:=save;
108         if q[head].x=n then
109         begin
110           flag:=true;
111           for i:=1 to 5 do
112             if s[i]>1 then flag:=false;
113           if flag then
114           if ans>f[q[head].x,q[head].y] then ans:=f[q[head].x,q[head].y];
115           inc(head);
116           continue;
117         end;
118         for i:=0 to 31 do
119           if i and a[q[head].x+1]=0 then
120           begin
121             for j:=1 to 5 do
122               t[j]:=(((a[q[head].x+1]+i)>>(j-1))and 1)*4;
123             k:=0;
124             for j:=1 to 5 do
125               if (s[j]>0) and (t[j]>0) then
126               begin
127                 t[j]:=s[j];
128                 k:=k or (1<<s[j]);
129               end;
130             flag:=true;
131             for j:=1 to 5 do
132               if (s[j]>0) and (k and (1<<s[j])=0) then flag:=false;
133             if flag=false then continue;
134             get(t);
135             k:=0;
136             for j:=5 downto 1 do
137               k:=k<<2+t[j];
138             if f[q[head].x+1,k]>500 then
139             begin
140               inc(tail);
141               q[tail].x:=q[head].x+1;
142               q[tail].y:=k;
143             end;
144             if f[q[head].x+1,k]>f[q[head].x,q[head].y]+bit(i) then f[q[head].x+1,k]:=f[q[head].x,q[head].y]+bit(i);
145           end;
146         inc(head);
147       end;
148     write(ans);
149 end;
150 
151 begin
152     init;
153     work;
154 end.
View Code

 

为什么会错呢,我写这个的时候,头脑有点乱,导致少考虑了一种情况(因为转移的时候联通块我是乱搞的)

2

11101

10111

这个我就会错

上面我是用10222表示的,然后转移到下面

就变成了14202然后把1附近的改成1(下一行的我全部用4来表示),就变成了11102,结果就错了

下面是改正后的代码

感谢zkyTimeMachine的帮助,查出了这个不易发现的错误,对于前面那个代码AC了我只能说数据太弱,刚好没出到这种数据

  1 const
  2     maxn=102;
  3 type
  4     node=record
  5       x,y:longint;
  6     end;
  7     aa=array[0..6]of longint;
  8 var
  9     f:array[0..maxn,0..1204]of longint;
 10     a:array[0..maxn]of longint;
 11     fa:array[1..4]of longint;
 12     flag:array[1..4]of boolean;
 13     n:longint;
 14 
 15 procedure init;
 16 var
 17     i,j:longint;
 18     s:char;
 19 begin
 20     readln(n);
 21     for i:=1 to n do
 22       begin
 23         for j:=1 to 5 do
 24           begin
 25             read(s);
 26             a[i]:=a[i]<<1+ord(s)-ord('0');
 27           end;
 28         readln;
 29       end;
 30     while n>0 do
 31       begin
 32         if a[n]>0 then break;
 33         dec(n);
 34       end;
 35     if n=0 then
 36     begin
 37       write(0);
 38       halt;
 39     end;
 40 end;
 41 
 42 procedure change(var a:aa;b,c:longint);
 43 var
 44     i:longint;
 45 begin
 46     for i:=1 to 5 do
 47       if a[i]=b then
 48       begin
 49         a[i]:=c;
 50         if (a[i-1]<>0) and (a[i-1]<10) then change(a,a[i-1],c);
 51         if (a[i+1]<>0) and (a[i+1]<10) then change(a,a[i+1],c);
 52       end;
 53 end;
 54 
 55 procedure get(var a:aa);
 56 var
 57     i,c:longint;
 58 begin
 59     c:=10;
 60     for i:=1 to 5 do
 61       if (a[i]<>0) and (a[i]<10) then
 62       begin
 63         inc(c);
 64         change(a,a[i],c);
 65       end;
 66     for i:=1 to 5 do
 67       if a[i]>0 then dec(a[i],10);
 68 end;
 69 
 70 function bit(x:longint):longint;
 71 begin
 72     if x=0 then exit(0);
 73     exit(bit(x-(x and -x))+1);
 74 end;
 75 
 76 var
 77     q:array[0..maxn*1024]of node;
 78 
 79 procedure work;
 80 var
 81     head,tail,i,j,k,ans,save:longint;
 82     s,t:aa;
 83     flag:boolean;
 84 begin
 85     fillchar(f,sizeof(f),1);
 86     t[0]:=0;
 87     t[6]:=0;
 88     ans:=500;
 89     f[0,0]:=0;
 90     q[1].x:=0;
 91     q[1].y:=0;
 92     head:=1;
 93     tail:=1;
 94     while head<=tail do
 95       begin
 96         save:=q[head].y;
 97         for i:=1 to 5 do
 98           begin
 99             s[i]:=q[head].y and 3;
100             q[head].y:=q[head].y>>2;
101           end;
102         q[head].y:=save;
103         if q[head].x=n then
104         begin
105           flag:=true;
106           for i:=1 to 5 do
107             if s[i]>1 then flag:=false;
108           if flag then
109           if ans>f[q[head].x,q[head].y] then ans:=f[q[head].x,q[head].y];
110           inc(head);
111           continue;
112         end;
113         for i:=0 to 31 do
114           if i and a[q[head].x+1]=0 then
115           begin
116             for j:=1 to 5 do
117               t[j]:=(((a[q[head].x+1]+i)>>(j-1))and 1)*(j+3);
118             k:=0;
119             for j:=1 to 5 do
120               if (s[j]>0) and (t[j]>0) then
121               begin
122                 t[j]:=s[j];
123                 k:=k or (1<<s[j]);
124               end;
125             flag:=true;
126             for j:=1 to 5 do
127               if (s[j]>0) and (k and (1<<s[j])=0) then flag:=false;
128             if flag=false then continue;
129             get(t);
130             k:=0;
131             for j:=5 downto 1 do
132               k:=k<<2+t[j];
133             if f[q[head].x+1,k]>500 then
134             begin
135               inc(tail);
136               q[tail].x:=q[head].x+1;
137               q[tail].y:=k;
138             end;
139             if f[q[head].x+1,k]>f[q[head].x,q[head].y]+bit(i) then f[q[head].x+1,k]:=f[q[head].x,q[head].y]+bit(i);
140           end;
141         inc(head);
142       end;
143     write(ans);
144 end;
145 
146 begin
147     init;
148     work;
149 end.
View Code

 

posted @ 2014-03-28 22:19 Randolph87 阅读(...) 评论(...) 编辑 收藏