[LuoguP1034][Noip2002] 矩形覆盖

[LuoguP1034][Noip2002] 矩形覆盖(Link

在平面上有(N)个点,(N)不超过五十, 要求将这(N)个点用(K)个矩形覆盖,(k)不超过(4),要求最小化矩形之和。

其实这个题应该是十分的简单,因为2002年蓝题的难度可想而知,一般都是思路简单码量大的题。这个题思路也就是十分暴力的枚举每一个点所属的矩阵的编号,然后题目要求所有的矩形不能重叠,于是就有了一个(Judge)函数,最后最小化矩形面积和就可以了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
typedef long long LL ;
const int MAXN = 51 ;
const int MAXM = 51 ;
const int Inf = 1e6  ;
int N, K, Ans = Inf, P ;
struct NODE {int X, Y ;} E[MAXN] ;
struct SQUR {int X[MAXN][3], Y[MAXN][3], V[MAXN] ; } Sq[5] ;

inline int maxx(int pos,int cos){if(pos>cos)return pos;else return cos;} 
inline int minn(int pos,int cos){if(pos>cos)return cos;else return pos;}

inline int Read() {
    int X = 0, F = 1 ; char ch = getchar() ;
    while (ch > '9' || ch < '0') F = (ch == '-' ? - 1 : 1), ch = getchar() ;
    while (ch >= '0' && ch <= '9') X=(X<<1)+(X<<3)+(ch^48), ch = getchar() ;
    return X * F ;
}

inline int Judge(int Now, int To) {
	int X[3], Y[3] ; X[1] = Y[1] = Inf, X[2] = Y[2] = - Inf ;
	X[1] = min(Sq[To].X[Now - 1][1], E[Now].X) ;
	X[2] = max(Sq[To].X[Now - 1][2], E[Now].X) ;
	Y[1] = min(Sq[To].Y[Now - 1][1], E[Now].Y) ;
	Y[2] = max(Sq[To].Y[Now - 1][2], E[Now].Y) ;
	for (int i = 1 ; i <= K ; i ++) if (i != To) {
		for (int k = 1 ; k <= 2 ; k ++) {
			Sq[i].X[Now][k] = Sq[i].X[Now - 1][k] ;
			Sq[i].Y[Now][k] = Sq[i].Y[Now - 1][k] ;
			Sq[i].V[Now] = Sq[i].V[Now - 1] ;
			for (int j = 1 ; j <= 2 ; j ++) {
				if (Sq[i].X[Now - 1][1] <= X[k] && Sq[i].X[Now - 1][2] >= X[k])
				if (Sq[i].Y[Now - 1][1] <= Y[j] && Sq[i].Y[Now - 1][2] >= Y[j])
					return Inf ;
			}
		}		
	}
	Sq[To].X[Now][1] = X[1] ; Sq[To].X[Now][2] = X[2] ;
	Sq[To].Y[Now][1] = Y[1] ; Sq[To].Y[Now][2] = Y[2] ;
	Sq[To].V[Now] = (X[2] - X[1]) * (Y[2] - Y[1]) ;
	return P = Sq[To].V[Now] - Sq[To].V[Now - 1] ;
}

inline void Dfs(int Now, int Sum) {
	if (Now == N + 1)
		Ans = Sum ;
	else for (int i = 1 ; i <= K ; i ++)
		if (Sum + Judge(Now, i) < Ans)
			Dfs(Now + 1, Sum + P) ;
}

int main() {
	N = Read(), K = Read() ;
	for (int i = 1 ; i <= N ; i ++) E[i].X = Read(), E[i].Y = Read() ;
	for (int i = 1 ; i <= 4 ; i ++)
		Sq[i].X[0][1] = Sq[i].Y[0][1] = Inf, 
		Sq[i].X[0][2] = Sq[i].Y[0][2] = - Inf ;
	Dfs(1, 0) ; 
	printf("%d", Ans) ; 
	return 0 ;
}
原文地址:https://www.cnblogs.com/sue_shallow/p/P1037.html