题目描述 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进制来表示每一行的状态表示(每一位表示这一格属于第几个联通块)

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

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

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

 const
maxn=;
type
node=record
x,y:longint;
end;
aa=array[..]of longint;
var
f:array[..maxn,..]of longint;
a:array[..maxn]of longint;
n:longint; procedure init;
var
i,j:longint;
s:char;
begin
readln(n);
for i:= to n do
begin
for j:= to do
begin
read(s);
a[i]:=a[i]<<+ord(s)-ord('');
end;
readln;
end;
while n> do
begin
if a[n]> then break;
dec(n);
end;
if n= then
begin
write();
halt;
end;
end; procedure get(var a:aa);
var
i,j,k,c:longint;
begin
c:=;
for i:= to do
for j:= to do
if a[j]=i then
begin
if i=c then inc(c);
k:=j;
while (k>) and (a[k-]>) do
begin
dec(k);
a[k]:=i;
end;
k:=j;
while (k<) and (a[k+]>) do
begin
inc(k);
a[k]:=i;
end;
end;
dec(c);
for i:= to do
if a[i]= then
begin
if a[i-]> then a[i]:=c
else
begin
inc(c);
a[i]:=c;
end;
end;
end; function bit(x:longint):longint;
begin
if x= then exit();
exit(bit(x-(x and -x))+);
end; var
q:array[..maxn*]of node; procedure work;
var
head,tail,i,j,k,ans,save:longint;
s,t:aa;
flag:boolean;
begin
fillchar(f,sizeof(f),);
t[]:=;
ans:=;
f[,]:=;
q[].x:=;
q[].y:=;
head:=;
tail:=;
while head<=tail do
begin
save:=q[head].y;
for i:= to do
begin
s[i]:=q[head].y and ;
q[head].y:=q[head].y>>;
end;
q[head].y:=save;
if q[head].x=n then
begin
flag:=true;
for i:= to do
if s[i]> then flag:=false;
if flag then
if ans>f[q[head].x,q[head].y] then ans:=f[q[head].x,q[head].y];
inc(head);
continue;
end;
for i:= to do
if i and a[q[head].x+]= then
begin
for j:= to do
t[j]:=(((a[q[head].x+]+i)>>(j-))and )*;
k:=;
for j:= to do
if (s[j]>) and (t[j]>) then
begin
t[j]:=s[j];
k:=k or (<<s[j]);
end;
flag:=true;
for j:= to do
if (s[j]>) and (k and (<<s[j])=) then flag:=false;
if flag=false then continue;
get(t);
k:=;
for j:= downto do
k:=k<<+t[j];
if f[q[head].x+,k]> then
begin
inc(tail);
q[tail].x:=q[head].x+;
q[tail].y:=k;
end;
if f[q[head].x+,k]>f[q[head].x,q[head].y]+bit(i) then f[q[head].x+,k]:=f[q[head].x,q[head].y]+bit(i);
end;
inc(head);
end;
write(ans);
end; begin
init;
work;
end.

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

2

11101

10111

这个我就会错

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

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

下面是改正后的代码

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

 const
maxn=;
type
node=record
x,y:longint;
end;
aa=array[..]of longint;
var
f:array[..maxn,..]of longint;
a:array[..maxn]of longint;
fa:array[..]of longint;
flag:array[..]of boolean;
n:longint; procedure init;
var
i,j:longint;
s:char;
begin
readln(n);
for i:= to n do
begin
for j:= to do
begin
read(s);
a[i]:=a[i]<<+ord(s)-ord('');
end;
readln;
end;
while n> do
begin
if a[n]> then break;
dec(n);
end;
if n= then
begin
write();
halt;
end;
end; procedure change(var a:aa;b,c:longint);
var
i:longint;
begin
for i:= to do
if a[i]=b then
begin
a[i]:=c;
if (a[i-]<>) and (a[i-]<) then change(a,a[i-],c);
if (a[i+]<>) and (a[i+]<) then change(a,a[i+],c);
end;
end; procedure get(var a:aa);
var
i,c:longint;
begin
c:=;
for i:= to do
if (a[i]<>) and (a[i]<) then
begin
inc(c);
change(a,a[i],c);
end;
for i:= to do
if a[i]> then dec(a[i],);
end; function bit(x:longint):longint;
begin
if x= then exit();
exit(bit(x-(x and -x))+);
end; var
q:array[..maxn*]of node; procedure work;
var
head,tail,i,j,k,ans,save:longint;
s,t:aa;
flag:boolean;
begin
fillchar(f,sizeof(f),);
t[]:=;
t[]:=;
ans:=;
f[,]:=;
q[].x:=;
q[].y:=;
head:=;
tail:=;
while head<=tail do
begin
save:=q[head].y;
for i:= to do
begin
s[i]:=q[head].y and ;
q[head].y:=q[head].y>>;
end;
q[head].y:=save;
if q[head].x=n then
begin
flag:=true;
for i:= to do
if s[i]> then flag:=false;
if flag then
if ans>f[q[head].x,q[head].y] then ans:=f[q[head].x,q[head].y];
inc(head);
continue;
end;
for i:= to do
if i and a[q[head].x+]= then
begin
for j:= to do
t[j]:=(((a[q[head].x+]+i)>>(j-))and )*(j+);
k:=;
for j:= to do
if (s[j]>) and (t[j]>) then
begin
t[j]:=s[j];
k:=k or (<<s[j]);
end;
flag:=true;
for j:= to do
if (s[j]>) and (k and (<<s[j])=) then flag:=false;
if flag=false then continue;
get(t);
k:=;
for j:= downto do
k:=k<<+t[j];
if f[q[head].x+,k]> then
begin
inc(tail);
q[tail].x:=q[head].x+;
q[tail].y:=k;
end;
if f[q[head].x+,k]>f[q[head].x,q[head].y]+bit(i) then f[q[head].x+,k]:=f[q[head].x,q[head].y]+bit(i);
end;
inc(head);
end;
write(ans);
end; begin
init;
work;
end.

1050 棋盘染色 2 - Wikioi的更多相关文章

  1. codevs——1049 棋盘染色

    1049 棋盘染色  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 有一个5×5的棋盘,上面有一 ...

  2. [codevs1050]棋盘染色 2

    [codevs1050]棋盘染色 2 试题描述 有一个5*N的棋盘,棋盘中的一些格子已经被染成了黑色,你的任务是对最少的格子染色,使得所有的黑色能连成一块. 输入 第一行一个整数N(<=100) ...

  3. 【wikioi】1049 棋盘染色(迭代深搜)

    http://www.wikioi.com/problem/1049/ 这题我之前写没想到迭代加深,看了题解,然后学习了这种搜索(之前我写的某题也用过,,但是不懂专业名词 囧.) 迭代加深搜索就是限制 ...

  4. codevs 1049 棋盘染色

    题目描述 Description 有一个5×5的棋盘,上面有一些格子被染成了黑色,其他的格子都是白色,你的任务的对棋盘一些格子进行染色,使得所有的黑色格子能连成一块,并且你染色的格子数目要最少.读入一 ...

  5. HDU 5402 Travelling Salesman Problem(棋盘染色 构造 多校啊)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5402 Problem Description Teacher Mai is in a maze wit ...

  6. [CodeVs1050]棋盘染色2(状态压缩DP)

    题目大意:有一个5*N(≤100)的棋盘,棋盘中的一些格子已经被染成了黑色,求最少对多少格子染色,所有的黑色能连成一块. 这题卡了我1h,写了2.6k的代码,清明作业一坨还没做啊...之前一直以为这题 ...

  7. CODEVS——T 1049 棋盘染色

    http://codevs.cn/problem/1049/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Descr ...

  8. hdu5601-N*M bulbs(黑白棋盘染色)

    一个矩形,一个人从左上角走到右下角,每走过一个位置把0变成1,1变成0. 求有没有可能他离开之后所有的数都是0 假设这个矩形是一个棋盘,黑白相间. 这样会发现从一个颜色走到相同颜色可以对棋盘不产生任何 ...

  9. [codevs1049]棋盘染色<迭代深搜>

    题目链接:http://codevs.cn/problem/1049/ 昨天的测试题里没有打出那可爱的迭代深搜,所以今天就来练一练. 这道题其实我看着有点懵,拿着题我就这状态↓ 然后我偷偷瞄了一眼hz ...

随机推荐

  1. PHP中的Trait

    Trait 自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait. Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制.Trait 为了减少单继承语言的限制, ...

  2. Linux 命令 - ftp: 网络文件传输工具

    命令格式 ftp [-pinegvd] [host] 命令参数 -A 传输文件模式为主动模式. -p 传输文件模式为被动模式. -i 关闭交互模式. -n 关闭自动登录功能. -e 不记录历史命令. ...

  3. SharpZipLib 压缩后传输给第三方平台无法识别问题

    问题描述:在项目中需要将文件压缩然后传输给三方进行彩信发送,使用SharpZipLib 进行压缩,原先使用J#进行压缩处理,但是用SharpZipLib压缩后的zip文件传输过去之后,总会报发送失败. ...

  4. iOS - 文件操作(File Operating)

    1. 沙盒 & NSData /*_______________________________获取沙盒路径_________________________________________* ...

  5. Cocos2d-x内置粒子系统

    从类图中我们可以看到,Cocos2d-x中有内置的11粒子,这些粒子的属性都是预先定义好的,我们也可以在程序代码中单独修改某些属性,我们在上一节的实例中都已经实现了这些属性的设置. 内置粒子系统 内置 ...

  6. IO&Seralize

    IO <appSettings> <!--日志路径--> <add key="LogPath" value="E:\学习\C#进阶\fsoc ...

  7. SharePoint Server 2013介绍v2

    SharePoint Server 2013介绍v2 http://wenku.baidu.com/link?url=rNYYoDmHcXmqhzOeA1sln5cS2xcnABYycBuz8Z4Oq ...

  8. (转)DES、RSA、MD5、SHA、随机生成加密与解密

    一.数据加密/编码算法列表   常见用于保证安全的加密或编码算法如下:   1.常用密钥算法   密钥算法用来对敏感数据.摘要.签名等信息进行加密,常用的密钥算法包括:   DES(Data Encr ...

  9. struts2使用struts2-bootstrap-plugin插件

    1.下载插件 http://code.google.com/p/struts2-bootstrap/ 2.添加maven依赖 <dependency> <groupId>com ...

  10. 在Windows下设置环境变量 运行mysql程序变得更容易

    在Windows下设置环境变量,点开始菜单,右键单击我的电脑--属性--高级--环境变量 可以看到PATH的变量是这样的: C:\WINDOWS;C:\WINDOWS\COMMAND   为了让运行m ...