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进制来表示每一行的状态表示(每一位表示这一格属于第几个联通块)
因为所有的黑色块都必须联通,所以上面的每一个不同的联通块至少有一个要延伸到下面来,这个转移的时候注意一下
对于每一个状态,枚举要下一层涂黑哪些块,然后转移,最后一层黑色都属于同一联通块才能更新答案
(这个代码其实是错的...下面还有一个)
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,结果就错了
下面是改正后的代码
感谢zky和TimeMachine的帮助,查出了这个不易发现的错误,对于前面那个代码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的更多相关文章
- codevs——1049 棋盘染色
1049 棋盘染色 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 有一个5×5的棋盘,上面有一 ...
- [codevs1050]棋盘染色 2
[codevs1050]棋盘染色 2 试题描述 有一个5*N的棋盘,棋盘中的一些格子已经被染成了黑色,你的任务是对最少的格子染色,使得所有的黑色能连成一块. 输入 第一行一个整数N(<=100) ...
- 【wikioi】1049 棋盘染色(迭代深搜)
http://www.wikioi.com/problem/1049/ 这题我之前写没想到迭代加深,看了题解,然后学习了这种搜索(之前我写的某题也用过,,但是不懂专业名词 囧.) 迭代加深搜索就是限制 ...
- codevs 1049 棋盘染色
题目描述 Description 有一个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 ...
- [CodeVs1050]棋盘染色2(状态压缩DP)
题目大意:有一个5*N(≤100)的棋盘,棋盘中的一些格子已经被染成了黑色,求最少对多少格子染色,所有的黑色能连成一块. 这题卡了我1h,写了2.6k的代码,清明作业一坨还没做啊...之前一直以为这题 ...
- CODEVS——T 1049 棋盘染色
http://codevs.cn/problem/1049/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Descr ...
- hdu5601-N*M bulbs(黑白棋盘染色)
一个矩形,一个人从左上角走到右下角,每走过一个位置把0变成1,1变成0. 求有没有可能他离开之后所有的数都是0 假设这个矩形是一个棋盘,黑白相间. 这样会发现从一个颜色走到相同颜色可以对棋盘不产生任何 ...
- [codevs1049]棋盘染色<迭代深搜>
题目链接:http://codevs.cn/problem/1049/ 昨天的测试题里没有打出那可爱的迭代深搜,所以今天就来练一练. 这道题其实我看着有点懵,拿着题我就这状态↓ 然后我偷偷瞄了一眼hz ...
随机推荐
- css3media响应式布局
响应式布局可以为不同终端的用户提供更加舒适的界面和更好的用户体验,而且随着目前大屏幕移动设备的 普及,用"大势所趋"来形容也不为过.随着越来越多的设计师采用这个技术,我们不仅看到很 ...
- 初识Less(2015年05月23日)
因为最近在研究Bootstrap,然后才了解到Less,听说Less很强大,又听说Bootstrap+Less会更搭,所以就决定也顺带了解下Less的相关知识. come on...... 一.简介 ...
- sort排序中的坑
问题的产生原因: 在一篇阿里面试题的跟帖中,很多人应用sort()方法对数组进行排序.看似合情合理的代码,运行结果却频频出错.为什么呢?因为很多人都忽略掉了一点,那就是sort()排序默认情况下是按A ...
- Entity Framework + WCF REST JSON Service
利用EF 和WCF 建立一个REST JSON Service. 首先我们要下载一个Visual Studio 的Template 叫 "ADO.NET C# POCO Entity Gen ...
- 为EditText设置OnTouchListener事件监听
在项目中需要在EditText输入前,判断某个值是否已经有值,有才可以输入,为NULL值则提示不让输入,先填写指定的编辑框 自己试过监听获取焦点事件,来设置setFocusable(true)或者se ...
- asp.net页面与页面之间传参数值
一.利用POST传值 传值asp文件send.aspx 代码如下 复制代码 <form id="form1" runat="server" action ...
- Eclipse Code Templates设置
从工作开始,经历了几个项目的开发,现在的项目一般都是一个团队共同开发,而每个人都有自己的编码习惯,为了统一格式,项目组在项目开发之前都会制定一系列的规范.俗话说约定优于配置,但是在执行过程中往往发现效 ...
- ios 微信细节
1.登录后,下次登录保存其用户名. * 官方的登录实现 * 1.把用户名和密码放在沙盒 NSString *user = self.userField.text; NSStri ...
- (转)mysql、sqlserver、oracle的默认事务的隔离级别
1.mysql的默认事务的隔离级别:可重复读取(repeatable read); 2.sqlserver的默认事务的隔离级别:提交读取(read committed); 3.oracle的默认事务的 ...
- (UVALive 7261)Xiongnu's Land 二分
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...