ZOJ-3209___Treasure Map —— DLX精确覆盖

2023-11-02 10:58

本文主要是介绍ZOJ-3209___Treasure Map —— DLX精确覆盖,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:点我啊╭(╯^╰)╮

题目大意:

    给你一个 n ∗ m n*m nm的矩形和 p p p 个小矩形,求最少需要几个小矩形可以精确覆盖这个大矩形???

解题思路:

    明显是最清晰的舞蹈链,那么问题就在于建图上,很多人接触这一题应该都是刚学完模板不久,这里要用 p p p 个小矩形来填满,求最少要几个,那么我们图形中的“行”就变成了这 p p p 个小矩形
    行的问题解决了,列呢??这里因为大矩形是 n ∗ m n*m nm,那么我们将这整个图分成 n ∗ m n*m nm个小正方形,这个图列就是 n ∗ m n*m nm
    换句话说,我们建的图是行为 p p p,列为 n ∗ m n*m nm 01 01 01 图,为什么是 n ∗ m n*m nm呢,因为每个小矩形最多由这么多个小正方形组成,相当于把每个矩形存放在了一行里(二维变一维)

代码思路:

    注意,这里与模板不同的是,模板只是找到了精确覆盖就返回,本题要求最小覆盖个数,不能带有返回值

核心:初步掌握舞蹈链的思想并加以转换

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;struct DancingLink{const static int N = 500010;const static int M = 1010;int n, s, ansd;	//列数 节点总数 int S[M], A[M], H[M];	// S[]该列节点总数  A[]答案  H[]行首指针 int L[N], R[N], U[N], D[N]; // L[],R[],U[],D[] 上下左右 int X[N], C[N];	// X[] C[] 行列编号 void init(int n){	// 初始化 this->n = n;for(int i=0; i<=n; i++)U[i]=i, D[i]=i, L[i]=i-1, R[i]=i+1;R[n]=0, L[0]=n; s=n+1;memset(S, 0, sizeof(S));memset(H, -1, sizeof(H));}void DelCol(int c){	// 删除列 L[R[c]]=L[c]; R[L[c]]=R[c];for(int i=D[c]; i!=c; i=D[i])for(int j=R[i]; j!=i; j=R[j])U[D[j]]=U[j], D[U[j]]=D[j], --S[C[j]];}void ResCol(int c){	// 恢复列 for(int i=U[c]; i!=c; i=U[i])for(int j=L[i]; j!=i; j=L[j])++S[C[j]], U[D[j]]=j, D[U[j]]=j;L[R[c]]=c, R[L[c]]=c;}void AddNode(int r,int c){	// 添加节点 ++S[c], C[++s]=c, X[s]=r;D[s]=D[c], U[D[c]]=s, U[s]=c, D[c]=s;if(H[r]<0) H[r]=L[s]=R[s]=s;	// 行首节点else R[s]=R[H[r]], L[R[H[r]]]=s, L[s]=H[r], R[H[r]]=s;}void dfs(int d){//深度,深搜遍历 if(ansd!=-1 && ansd<=d) return;if(!R[0]){if(ansd==-1 || ansd>d) ansd=d;return;}int c=R[0];for(int i=R[0]; i; i=R[i]) if(S[i]<S[c]) c=i;DelCol(c);for(int i=D[c]; i!=c; i=D[i]){A[d]=X[i];for(int j=R[i]; j!=i; j=R[j]) DelCol(C[j]);dfs(d+1);for(int j=L[i]; j!=i; j=L[j]) ResCol(C[j]);}ResCol(c);}
} dlx; int main(){int cas, n, m, p;scanf("%d", &cas);while(cas--) {scanf("%d%d%d", &n, &m, &p);dlx.init(n*m);for(int k=1; k<=p; k++) {int x1, x2, y1, y2;scanf("%d%d%d%d", &x1, &y1, &x2, &y2);for(int i=x1+1; i<=x2; i++)for(int j=y1+1; j<=y2; j++)dlx.AddNode(k, m*(i-1)+j);}dlx.ansd=-1;dlx.dfs(0);printf("%d\n",dlx.ansd);}
}

这篇关于ZOJ-3209___Treasure Map —— DLX精确覆盖的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/330125

相关文章

数论ZOJ 2562

题意:给定一个数N,求小于等于N的所有数当中,约数最多的一个数,如果存在多个这样的数,输出其中最大的一个。 分析:反素数定义:对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数。 性质一:一个反素数的质因子必然是从2开始连续的质数。 性质二:p=2^t1*3^t2*5^t3*7

最大流=最小割=最小点权覆盖集=sum-最大点权独立集

二分图最小点覆盖和最大独立集都可以转化为最大匹配求解。 在这个基础上,把每个点赋予一个非负的权值,这两个问题就转化为:二分图最小点权覆盖和二分图最大点权独立集。   二分图最小点权覆盖     从x或者y集合中选取一些点,使这些点覆盖所有的边,并且选出来的点的权值尽可能小。 建模:     原二分图中的边(u,v)替换为容量为INF的有向边(u,v),设立源点s和汇点t

zoj 1721 判断2条线段(完全)相交

给出起点,终点,与一些障碍线段。 求起点到终点的最短路。 枚举2点的距离,然后最短路。 2点可达条件:没有线段与这2点所构成的线段(完全)相交。 const double eps = 1e-8 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;

zoj 4624

题目分析:有两排灯,每排n个,每个灯亮的概率为p,每个灯之间互不影响,亮了的灯不再灭,问两排中,每排有大于等于m个灯亮的概率。 设dp[ i ][ j ]为第一排亮了i个灯,第二排亮了j个灯,距离目标状态的期望天数。显然 i >= m ,j >= m时 , dp[ i ][ j ] = 0 。 状态转移 : 第一排亮了a个灯,a 在[ 0 , n - i] 之间,第二排亮了b个灯 , b 在

zoj 3228 ac自动机

给出一个字符串和若干个单词,问这些单词在字符串里面出现了多少次。单词前面为0表示这个单词可重叠出现,1为不可重叠出现。 Sample Input ab 2 0 ab 1 ab abababac 2 0 aba 1 aba abcdefghijklmnopqrstuvwxyz 3 0 abc 1 def 1 jmn Sample Output Case 1 1 1 Case 2

ZOJ Monthly, August 2014小记

最近太忙太忙,只能抽时间写几道简单题。不过我倒是明白要想水平提高不看题解是最好的了。 A  我只能死找规律了,无法证明 int a[50002][2] ;vector< vector<int> > gmax , gmin ;int main(){int n , i , j , k , cmax , cmin ;while(cin>>n){/* g

POJ3041 最小顶点覆盖

N*N的矩阵,有些格子有物体,每次消除一行或一列,最少要几次消灭完。 行i - >列j 连边,表示(i,j)处有物体,即 边表示 物体。 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;impo

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

Map

Map 是 Java 中用于存储键值对的集合接口。以下是对 Map 的详细介绍: 特点 键值对存储:每个元素包含一个键和一个值。 键唯一:键不能重复,但值可以重复。 无序/有序:根据具体实现,键值对的顺序可能无序(如 HashMap)或有序(如 TreeMap、LinkedHashMap)。 主要实现类 HashMap 基于哈希表,无序存储。 允许一个 null 键和多个 null 值。

Minimal coverage -uva 覆盖线段,贪心

一道经典的贪心问题,具体方法就是将(an,bn)区间,按照an从小到大的顺序进行排序,之后从0开始, 取最大的有效区间,这里用到了结构体的快排,否则可能会超时. #include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_SIZE 100000 + 10#define BOTTOM -50000 - 10str