题目描述 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. Tomcat - DBCP 配置

    1. Database configuration Create a new test user, a new database and a single test table. Your MySQL ...

  2. SNMP监控一些常用OID的总结

    做网络监控的人对SNMP的协议肯定够很熟悉,下面罗列出一些常见的OID说明,方便大家省去查阅相关资料的麻烦. 系统参数(1.3.6.1.2.1.1) OID 描述 备注 请求方式 .1.3.6.1.2 ...

  3. 解决ASP.NET网站发布问题

    目录 前言 开始 aspx.cs文件放到单独的类库项目 一个可选择勾选页面的发布工具:LimusicAddin 前言 Asp.net 发布分为:动态编译和预编译.预编译又分为:In Place Pre ...

  4. Android Wi-Fi基本操作

    从用户角度看,Android Wi-Fi模块自下向上可以看为5层:硬件驱动程序,wpa_suppplicant,JNI,WiFi API,WifiSettings应用程序. 1.wpa_supplic ...

  5. 【转载】颜色空间-RGB、HSI、HSV、YUV、YCbCr的简介

    转载自缘佳荟的博客. 颜色通常用三个相对独立的属性来描述,三个独立变量综合作用,自然就构成一个空间坐标,这就是颜色空间.而颜色可以由不同的角度,用三个一组的不同属性加以描述,就产生了不同的颜色空间.但 ...

  6. jquery获取文档高度和窗口高度的例子

    jquery获取文档高度和窗口高度,$(document).height().$(window).height() $(document).height():整个网页的文档高度 $(window).h ...

  7. js(jQuery)获取时间搜集

    获取JavaScript 的时间使用内置的Date函数完成 var mydate = new Date(); mydate.getYear(); //获取当前年份(2位) mydate.getFull ...

  8. 40个容易上瘾的HTML5网页游戏,总有一款适合你

    我记得姐姐家的孩子在刚刚才学会走路,说话还不能完整的时候就已经能自己用小手点出小游戏的网站来一个人自娱自乐.我一直在想这一代跟着计算机一起茁壮成长的孩子会不会也和美国那一代人一样,出现9岁的黑客和计算 ...

  9. ZigBee2006,2007,pro各个版本的区别

    文章转载自http://home.eeworld.com.cn/my/space-uid-361439-blogid-224722.html

  10. iOS 非ARC基本内存管理系列 2-多对象内存管理(1)

    单个对象的内存管理非常简单无非就是alloc对应release,retain对应release.但是如果涉及到很多对象,而且对象与对象有联系的时候该怎么去管理对象的内存呢. 比如同样一本书有好3个人购 ...