[DLX重复覆盖] hdu 3529 Bomberman - Just Search!
2015-07-20 21:48
465 查看
题意:
给你N*M的图,*是破坏不了的墙,#是需要你破坏的前,.是可以放***的地方。
每个点只能放一个***,同时放***,***是四个方向无限距离,能被墙挡住。
问你最少放多少个***,能把所以#炸掉。
思路:
对每个.进行编号,以及每个#进行编号。
.为行,#为列建图。
跑DLX重复覆盖即可。
代码:
给你N*M的图,*是破坏不了的墙,#是需要你破坏的前,.是可以放***的地方。
每个点只能放一个***,同时放***,***是四个方向无限距离,能被墙挡住。
问你最少放多少个***,能把所以#炸掉。
思路:
对每个.进行编号,以及每个#进行编号。
.为行,#为列建图。
跑DLX重复覆盖即可。
代码:
#include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"algorithm" #include"iostream" #include"map" #include"vector" #define mod 1000000007 #define ll long long using namespace std; #define N 1010*100 #define RN 1010 #define CN 1010 struct DLX { int n,m,C; int U ,D ,L ,R ,Row ,Col ; int H[RN],S[CN],cnt,ans[RN]; void init(int _n,int _m) { n=_n; m=_m; for(int i=0; i<=m; i++) { S[i]=0; U[i]=D[i]=i; L[i]=(i==0?m:i-1); R[i]=(i==m?0:i+1); } C=m; for(int i=1; i<=n; i++) H[i]=-1; } void link(int x,int y) { C++; Row[C]=x; Col[C]=y; S[y]++; U[C]=U[y]; D[C]=y; D[U[y]]=C; U[y]=C; if(H[x]==-1) H[x]=L[C]=R[C]=C; else { L[C]=L[H[x]]; R[C]=H[x]; R[L[H[x]]]=C; L[H[x]]=C; } } void del(int x) { for(int i=D[x]; i!=x; i=D[i]) { R[L[i]]=R[i]; L[R[i]]=L[i]; } } void rec(int x) { for(int i=U[x]; i!=x; i=U[i]) { R[L[i]]=i; L[R[i]]=i; } } int used[CN]; int h() { int sum=0; for(int i=R[0]; i!=0; i=R[i]) used[i]=0; for(int i=R[0]; i!=0; i=R[i]) { if(used[i]==0) { sum++; used[i]=1; for(int j=D[i]; j!=i; j=D[j]) for(int k=R[j]; k!=j; k=R[k]) used[Col[k]]=1; } } return sum; } void dance(int x) { if(x+h()>=cnt) return ; if(R[0]==0) { cnt=min(cnt,x); return ; } int now=R[0]; for(int i=R[0]; i!=0; i=R[i]) { if(S[i]<S[now]) now=i; } for(int i=D[now]; i!=now; i=D[i]) { del(i); for(int j=R[i]; j!=i; j=R[j]) del(j); dance(x+1); for(int j=L[i]; j!=i; j=L[j]) rec(j); rec(i); } return ; } } dlx; char mp[22][22]; int num[22][22]; int main() { int n,m; while(scanf("%d%d",&n,&m)!=-1) { int sum=0; for(int i=0;i<n;i++) scanf("%s",mp[i]); memset(num,0,sizeof(num)); int cnt=0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(mp[i][j]=='.') sum++; if(mp[i][j]=='#') num[i][j]=++cnt; } } dlx.init(sum,cnt); int bh=0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(mp[i][j]!='.') continue; bh++; for(int k=1;;k++) { if(mp[i+k][j]=='*') break; if(mp[i+k][j]=='#') { dlx.link(bh,num[i+k][j]); break; } } for(int k=1;;k++) { if(mp[i-k][j]=='*') break; if(mp[i-k][j]=='#') { dlx.link(bh,num[i-k][j]); break; } } for(int k=1;;k++) { if(mp[i][j+k]=='*') break; if(mp[i][j+k]=='#') { dlx.link(bh,num[i][j+k]); break; } } for(int k=1;;k++) { if(mp[i][j-k]=='*') break; if(mp[i][j-k]=='#') { dlx.link(bh,num[i][j-k]); break; } } } } dlx.cnt=15*15+100; dlx.dance(0); printf("%d\n",dlx.cnt); } return 0; }
相关文章推荐
- 陈嘉 2015/07/10 个人文档
- 如何在虚拟机中安装linux系统
- [剑指Offer]12.二进制中1的个数
- 赵晓铮 2015/7/16 个人文档
- 关于#ifndef,#define,#end的说明
- IOS基本数据类型的包装类
- 简单问题的八种排序方法
- View Controller 生命周期
- 课程笔记 06:数据结构(清华) 列表-节点
- 自定义tarBar
- 【leetcode】Product of Array Except Self
- 基于selenium的pyse自动化测试框架
- 机器学习算法与Python实践之(三)支持向量机(SVM)进阶
- 1009 数字1的数量
- 玩转iOS 9的UIDynamics
- Remove Element
- K-means聚类算法
- sun.jnu.encoding
- hibernate学习之路——hello word
- Oracle的触发器