【poj2226】 Muddy Fields
http://poj.org/problem?id=2226 (题目链接)
题意
给出一个只包含‘.’和‘*’的矩阵,用任意长度的宽为1的木板覆盖所有的‘*’而不覆盖‘.’,木板必须跟矩形的长或宽平行。问最少需要多少块木板。
Solution
这道题的构图非常巧妙,堪称经典构图。对于每一个‘*’,要么就是被横的木板覆盖,要么就是被竖的木板覆盖,而木板的长度一定都是取到最长(因为题目没有说木板不能重叠,所以木板尽可能长不会使答案变大)。
假设我们全部用横木板进行覆盖,那么可以很简单的统计出哪些地方用第几块木板覆盖;同样如果我们全部用竖的木板进行覆盖,也可以统计出哪些地方用第几块木板覆盖。所以我们最后要选择的木板就在这些木板中产生。
拿样例来举个例子:
横:1 0 2 0 竖:1 0 4 0
0 3 3 3 0 3 4 5
4 4 4 0 2 3 4 0
0 0 5 0 0 0 4 0
所以现在问题就转化成了如何选取最少的木板,使所有的‘*’都被覆盖。这是不是很像二分图匹配中的最小点覆盖,可问题是我们怎么对它构图呢?
对于每一个‘*’,都会有一个横木板和竖木板在这个位置相交。那么如果我们对于每一个‘*’给在这里相交的横木板和竖木板的编号连一条边,是不是每一条边都表示一个‘*’呢?答案是显然的。问题到这里也就迎刃而解了。最小点覆盖=最大匹配数,所以我们只需要连完边后跑匈牙利就可以了。
代码
// poj2226
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<string>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;
inline LL getint() {
int f,x=0;char ch=getchar();
while (ch<='0' || ch>'9') {if (ch=='-') f=-1;else f=1;ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int maxn=1000;
struct edge {int to,next;}e[maxn*maxn];
int n,m,cnt,head[maxn],a[maxn][maxn],x[maxn][maxn],y[maxn][maxn],p[maxn],vis[maxn];
char s[maxn]; void insert(int u,int v) {
e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;
}
bool find(int x) {
for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]) {
vis[e[i].to]=1;
if (p[e[i].to]==0 || find(p[e[i].to])) {
p[e[i].to]=x;
return 1;
}
}
return 0;
}
int main() {
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) {
scanf("%s",s);
for (int j=0;j<m;j++) {
if (s[j]=='*') a[i][j+1]=1;
else a[i][j+1]=0;
}
}
int xx=0,yy=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++) if (a[i][j]>0) {
x[i][j]=++xx;
while (j<m && a[i][j+1]>0) {j++;x[i][j]=xx;}
}
for (int j=1;j<=m;j++)
for (int i=1;i<=n;i++) if (a[i][j]>0) {
y[i][j]=++yy;
while (i<n && a[i+1][j]>0) {i++;y[i][j]=yy;}
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (a[i][j]>0) insert(x[i][j],y[i][j]);
int ans=0;
for (int i=1;i<=xx;i++) {
for (int j=1;j<=yy;j++) vis[j]=0;
if (find(i)) ans++;
}
printf("%d\n",ans);
return 0;
}
【poj2226】 Muddy Fields的更多相关文章
- 【POJ2226】Muddy Fields
题目大意:给定一个 N*M 的图,图中有一些格子不能被任何东西覆盖,现有一些宽度为 1,长度任意的骨牌覆盖这些可以被覆盖的格子,骨牌之间可以重叠,求将所有可以被覆盖的格子覆盖所需的最小骨牌数是多少. ...
- 【poj3254】Corn Fields 状态压缩dp
AC通道:http://vjudge.net/problem/POJ-3254 [题目大意] 农夫约翰购买了一处肥沃的矩形牧场,分成M*N(1<=M<=12; 1<=N<=12 ...
- 【POJ3254】Corn Fields 状压DP第一次
!!!!!!! 第一次学状压DP,其实就是运用位运算来实现一些比较,挺神奇的.. 为什么要发“!!!”因为!x&y和!(x&y)..感受一下.. #include <iostre ...
- 【poj3254】 Corn Fields
http://poj.org/problem?id=3254 (题目链接) 题意 给出一块n*m的田地,有些能够耕种,有些不能.要求将牛两两不相邻的放在田中,牛的个数至少为1个.问有多少种放法. So ...
- 【POJ3254】Corn Fields
http://poj.org/problem?id=3254 题意:给你一块n*m(0<n,m<=12)的地图,其中有的方格是肥沃的(用1表示),有的方格是贫瘠的(用0表示).现在约翰要在 ...
- 【POJ3254】Corn Fields(状压DP)
题意: 一个M x N矩阵里有很多格子,每个格子有两种状态,可以放牧和不可以放牧,可以放牧用1表示,否则用0表示,在这块牧场放牛,要求两个相邻的方格不能同时放牛,即牛与牛不能相邻.问有多少种放牛方案( ...
- 【BZOJ1725】[Usaco2006 Nov]Corn Fields牧场的安排 状压DP
[BZOJ1725][Usaco2006 Nov]Corn Fields牧场的安排 Description Farmer John新买了一块长方形的牧场,这块牧场被划分成M列N行(1<=M< ...
- 【BZOJ】1725: [Usaco2006 Nov]Corn Fields牧场的安排
[算法]状压DP [题解]对于上一行的每个状态,每行进行DFS. #include<cstdio> #include<algorithm> #include<cstrin ...
- 【USACO 2006 November Gold】Corn Fields
[题目链接] 点击打开链接 [算法] 状压DP [代码] #include<bits/stdc++.h> using namespace std; #define MAXN 12 #def ...
随机推荐
- 在Android Studio中使用shareSDK进行社会化分享(图文教程)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- 使用Unity3D引擎开发赛车游戏
Car Tutorial 在Unity3D的Asset Store有一个赛车的Demo —— Car Tutorial,看起来特别酷的赛车游戏Demo,不过我还没有下载下来,因为在公司下载Assets ...
- Linux安装、卸载软件
在linux环境中,尤其是cenos中安装过一些软件,一般是二进制安装与源码安装,现小结一下linux中的安装与卸载. 一.通常Linux应用软件的安装包有三种: 1) tar包,如software- ...
- java 20 -2 递归之找特定目录下的特定格式文件
/* 需求:把C:\Users\Administrator\Desktop\记录目录下所有以.java结尾的文件的绝对路径输出到控制台 分析: A:封装该目录 B:获取该目录下的所有文件或文件夹的Fi ...
- f2fs解析(十)nid 如何从nat_root中删除
上面我们谈到了一个nid如何从free_nid中转移到node_info中去[分别有一个链表和一棵基数树搭伙做事],讲free_nid时,详细说明了free_nid中是如何进如何出的,上一篇说了nid ...
- 07Spring_bean属性的依赖注入-重点@Autowriter
在spring2.5 版本,没有提供基本类型属性注入 ,但是spring3.0引入注解@Value 所以在Spring3.0中属性的注入只可以这么写.
- MVC权限验证之ActionFilterAttribute
参考:http://www.cnblogs.com/waitingfor/archive/2011/12/27/2303784.html ActionFilterAttribute是Action过滤类 ...
- 第三章 续:时间控件(TimePicker)
上一章,介绍了datetimepicker使用, 然而,当只需要时分秒的时候,它并不怎么理想,因此又找了一个单独的时间控制插件 现在介绍一个timepicker,用法差不多,但是它只是基于bootst ...
- 入门Linux
45分钟带你入门Linux(附:笔者在工作室开讨论班录制的视频讲解) 第一部分 熟悉Linux基本操作 一.初识Linux 1.Linux特点 ◊ 开放性 ◊ 多用户 ◊ 多任务 ◊ ...
- Linux Linux程序练习九
题目:利用多线程与有名管道技术,实现两个进程之间发送即时消息,实现聊天功能 思路:关键在于建立两个有名管道,利用多线程技术,进程A中线程1向管道A写数据,进程B中线程2从管道A读数据,进程A线程2从管 ...