洛谷 P1034 矩形覆盖

题目描述

在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示。例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一。

这些点可以用 k 个矩形(1<=k<=4)全部覆盖,矩形的边平行于坐标轴。当 k=2 时,可用如图二的两个矩形 sl,s2 覆盖,s1,s2 面积和为 4。问题是当 n 个点坐标和 k 给出后,怎样才能使得覆盖所有点的 k 个矩形的面积之和为最小呢。约定:覆盖一个点的矩形面积为 0;覆盖平行于坐标轴直线上点的矩形面积也为0。各个矩形必须完全分开(边线与顶点也都不能重合)。

输入输出格式

输入格式:

 

n k xl y1 x2 y2 ... ...

xn yn (0<=xi,yi<=500)

 

输出格式:

 

输出至屏幕。格式为:

一个整数,即满足条件的最小的矩形面积之和。

 

输入输出样例

输入样例#1:
4 2
1 1
2 2
3 6
0 7
输出样例#1:
4
思路:深搜,枚举每个点放在哪个矩形中
吐槽:(╯‵□′)╯︵┻━┻,cogs上第6组数据竟然是错误的,害我调试了辣么久。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,k,ans=0x7f7f7f7f,val;
struct nond{
    int x,y;
}v[60];
struct none{
    int l,r,u,d; //记录这个矩形的四极。 
    bool falg;    //判断这个矩形内有没有点 
}f[5];
int judge(int i,int j){
    if(f[i].l<=f[j].l&&f[i].r>=f[j].l&&f[i].d>=f[j].d&&f[i].u<=f[j].d)    return 1;
    if(f[i].l<=f[j].r&&f[i].r>=f[j].r&&f[i].d>=f[j].d&&f[i].u<=f[j].d)    return 1;
    if(f[i].l<=f[j].l&&f[i].r>=f[j].l&&f[i].d>=f[j].u&&f[i].u<=f[j].u)    return 1;
    if(f[i].l<=f[j].r&&f[i].r>=f[j].r&&f[i].d>=f[j].u&&f[i].u<=f[j].u)    return 1;
    return 0;
}
void dfs(int num){
    val=0;
    for(int i=1;i<=k;i++){
        if(f[i].falg)
            for(int j=i+1;j<=k;j++)
                if(f[j].falg&&judge(i,j))    return ;
        val+=(f[i].r-f[i].l)*(f[i].d-f[i].u);//统计到目前为止的矩形的面积和。 
    }
    if(val>=ans)    return;
    if(num>n){
        ans=val;
        return ;
    }
    for(int i=1;i<=k;i++){
        none tmp=f[i];
        if(!f[i].falg){
            f[i].falg=1;
            f[i].l=f[i].r=v[num].x;
            f[i].d=f[i].u=v[num].y;
            dfs(num+1);
            f[i]=tmp;
        }
        else{
            f[i].l=min(f[i].l,v[num].x);
            f[i].r=max(f[i].r,v[num].x);
            f[i].u=min(f[i].u,v[num].y);
            f[i].d=max(f[i].d,v[num].y);
            dfs(num+1);
            f[i]=tmp;
        }
    }
}
int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&v[i].x,&v[i].y);
    dfs(1);
    cout<<ans;
}
 
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
原文地址:https://www.cnblogs.com/cangT-Tlan/p/7466067.html