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

 

你可能感兴趣的:(IO)