题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=31370

题意:用尽量少r*c的小矩形覆盖大矩形n*m中的所有1,将所有1转换成size列,然后以大矩形的每点当成小矩形r*c的左上角覆盖到的1当成一行,问题则转换成m*n行中选尽量少的行来覆盖所有列。。。

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 10007
#define inf 0x3f3f3f3f
#define N 100010
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxnode=;
const int MaxN=;
const int MaxM=;
struct DLX
{
int n,m,size;
int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
int H[MaxN],S[MaxM];
int ansd,ans[MaxN];
void init(int _n,int _m)
{
n=_n;m=_m;
for(int i=;i<=m;i++)
{
S[i]=;
U[i]=D[i]=i;
L[i]=i-;
R[i]=i+;
}
R[m]=;L[]=m;
size=m;
for(int i=;i<=n;i++)H[i]=-;
}
void Link(int r,int c)
{
++S[Col[++size]=c];
Row[size]=r;
D[size]=D[c];
U[D[c]]=size;
U[size]=c;
D[c]=size;
if(H[r]<)H[r]=L[size]=R[size]=size;
else
{
R[size]=R[H[r]];
L[R[H[r]]]=size;
L[size]=H[r];
R[H[r]]=size;
}
}
void Remove(int c)
{
for(int i = D[c];i != c;i = D[i])
L[R[i]] = L[i], R[L[i]] = R[i];
}
void Resume(int c)
{
for(int i = U[c];i != c;i = U[i])
L[R[i]]=R[L[i]]=i;
} bool vis[maxnode];
int h()
{
int res=;
for(int c=R[];c!=;c=R[c])vis[c]=true;
for(int c=R[];c!=;c=R[c])
if(vis[c])
{
res++;
vis[c]=false;
for(int i=D[c];i!=c;i=D[i])
for(int j=R[i];j!=i;j=R[j])
vis[Col[j]]=false;
}
return res;
}
void Dance(int d)//d为递归深度
{
if(d+h()>=ansd)return;
if(R[]==)//找到解
{
if(d<ansd)ansd=d;
return;
}
//找S最小的C列
int c=R[];//第一个未删除的列
for(int i=R[];i!=;i=R[i])
if(S[i]<S[c])c=i;
for(int i=D[c];i!=c;i=D[i])//用结点i所在的行覆盖第c列
{
Remove(i);
for(int j=R[i];j!=i;j=R[j])Remove(j);//删除节结点i所在行覆盖第c列
Dance(d+);
for(int j=L[i];j!=i;j=L[j])Resume(j);// 恢复
Resume(i);
}
}
};
DLX g;
int id[][];
int main()
{
int n,m,x,c,r;
while(scanf("%d%d",&n,&m)>)
{
int sz=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
scanf("%d",&x);
id[i][j]=x?++sz:;
}
g.init(n*m,sz);
scanf("%d%d",&r,&c);
for(int i=,num=;i<=n;i++)
for(int j=;j<=m;j++,num++)
{
for(int x=;x+i<=n&&x<r;x++)
for(int y=;y+j<=m&&y<c;y++)
if(id[i+x][y+j])
g.Link(num,id[i+x][j+y]);
}
g.ansd=n*m;
g.Dance();
printf("%d\n",g.ansd);
}
}

FZU 1686(重复覆盖)的更多相关文章

  1. FZU 1686 神龙的难题 (重复覆盖)

    Problem 1686 神龙的难题 Accept: 397    Submit: 1258Time Limit: 1000 mSec    Memory Limit : 32768 KB  Prob ...

  2. FZU Problem 1686 神龙的难题 重复覆盖

    题目链接 给出大矩形的长宽, 矩形里面有1,0两个值, 给出小矩形的长宽, 求用最少的小矩形覆盖所有的1. 重复覆盖的模板题. #include <iostream> #include & ...

  3. (简单) FZU 1686 神龙的难题 , DLX+可重复覆盖。

    Description 这是个剑与魔法的世界.英雄和魔物同在,动荡和安定并存.但总的来说,库尔特王国是个安宁的国家,人民安居乐业,魔物也比较少.但是.总有一些魔物不时会进入城市附近,干扰人民的生活.就 ...

  4. FZU 2165 v11(最小重复覆盖)+ codeforces 417D Cunning Gena

    告诉你若干个(<=100)武器的花费以及武器能消灭的怪物编号,问消灭所有怪物(<=100)的最小花费...当然每个武器可以无限次使用,不然这题就太水了╮(╯▽╰)╭ 这题当时比赛的时候连题 ...

  5. FZU 1686 神龙的难题(DLX反复覆盖)

    FZU 1686 神龙的难题 pid=1686" target="_blank" style="">题目链接 题意:中文题 思路:每个1看成列, ...

  6. FZU 1686 神龙的难题 (DLX)

    神龙的难题 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status ...

  7. DLX 舞蹈链 精确覆盖 与 重复覆盖

    精确覆盖问题:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 还有重复覆盖问题 dancing links 是 一种数据结构,用来优化搜索,不算是一种算法.(双向 ...

  8. (中等) HDU 3335 , DLX+重复覆盖。

    Description As we know,the fzu AekdyCoin is famous of math,especially in the field of number theory. ...

  9. DLX精确覆盖与重复覆盖模板题

    hihoCoder #1317 : 搜索四·跳舞链 原题地址:http://hihocoder.com/problemset/problem/1317 时间限制:10000ms 单点时限:1000ms ...

  10. HDU 2295 Radar (重复覆盖)

    Radar Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

随机推荐

  1. Google用户登录界面 Android实现

    实验效果: 项目目录: Java代码(放在Src文件下) package com.bn.chap9.login; import java.io.BufferedReader; import java. ...

  2. ubuntu12.04 安装 opencv 2.4.8(非源代码编译)

    一:安装所须要的各种库,如GTK3.xx 安装GCC:sudo apt-get install build-essential 安装CMakesudo apt-get install cmake su ...

  3. [置顶] 手把手教你iOS消息推送证书生成以及Push消息

    iOS推送消息是许多iOS应用都具备的功能,今天在给应用加推送功能,在生成证书的过程中,发生了各种令人蛋痛的事.下面就把步骤拿出来分享下: iOS消息推送的工作机制可以简单的用下图来概括: Provi ...

  4. [课堂实践与项目]IOS优先级的计算器

    这个计算器主要是使用数组进行实现的.虽然没有使用前缀后缀表达式,但是是一种方法o. .h文件 // // LCViewController.h // 具有优先级的calculator // // Cr ...

  5. PrimusUI

    小身材大用途,用PrimusUI驾驭你的页面 “PrimusUI”是自己在借鉴了如今网上很多开源的UI库,再经过自己整理加工的一个简单代码集合. 每个功能块的CSS代码都很少,力求简单易懂,低门槛,代 ...

  6. Windows 8 动手实验系列教程 实验7:磁贴和通知

    动手实验 实验7:磁贴和通知 2012年9月 简介 磁贴是Windows应用商店应用用户体验的重要元素.当应用程序被安装后,它的磁贴将在Windows 8开始屏幕被创建.该磁贴(称为主磁贴)作为启动应 ...

  7. Android开发者指南-用户界面-拖放-Drag and Drop[原创译文]

      英文原文:http://developer.android.com/guide/topics/ui/drag-drop.html 版本:Android 4.0 r1 译者注:黄色底色为未决译文 快 ...

  8. c#(winform,webform通用)利用npoi将xls文件复制为xlsx文件(excel的修改,保存,包括excel2003-office2007+的处理)

    1.程序界面 每次需要处理excel文件的时候,都是去百度找方案,真是气一头火,今天好好总结一下,下次就不用度娘了. 我是用winform来试验的,因为winform比较方便测试,实际上只要是在.ne ...

  9. Data Recovery Advisor(数据恢复顾问)

    Data Recovery Advisor 是11g新特性,是Oracle顾问程序架构的一部分,它会在遇到错误时自动收集有关故障信息.如果主动运行Data Recovery Advisor,通常可以在 ...

  10. 引导加载程序:GRUB

    计算机在启动的时候,首先由BIOS中的程序执行自检,自检通过后,就根据CMOS的配置找到第一个可启动磁盘的MBR中的Boot Loader程序(一般在启动盘的第一个物理扇区,占446字节),并把控制权 ...