P1034 矩形覆盖

题目描述

在平面上有nn个点(n \le 50n≤50),每个点用一对整数坐标表示。例如:当 n=4n=4 时,44个点的坐标分另为:p_1p1​(1,11,1),p_2p2​(2,22,2),p_3p3​(3,63,6),P_4P4​(0,70,7),见图一。

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

输入输出格式

输入格式:

 

n knk
x_1 y_1x1​y1​
x_2 y_2x2​y2​
... ...

x_n y_nxn​yn​ (0 \le x_i,y_i \le 5000≤xi​,yi​≤500)

 

输出格式:

 

输出至屏幕。格式为:

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

 

输入输出样例

输入样例#1: 复制

4 2
1 1
2 2
3 6
0 7

输出样例#1: 复制

4

 

没懂代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,R,zt[55],a[10] = {0},best=0x7fffffff;
int maxn,may,mix,miy;
struct node {
    int x,y;
} w[510];
void pint() {
    int s=0;
    maxn=may=0;
    mix=miy=0x7fffffff;
    for(int i=1; i<=R; i++) {
        for(int j=a[i-1]+1; j<=a[i]; j++) {
            maxn=max(w[j].x,maxn);
            mix=min(w[j].x,mix);
            may=max(w[j].y,may);
            miy=min(w[j].y,miy);
        }
        s+=(maxn-mix)*(may-miy);
        maxn=may=0;
        mix=miy=0x7fffffff;
    }
    if(s<best) {
        best=s;
    }
}
void sousuo(int k) {
    if(R==k) {
        pint();
        return ;
    }
    for(int i=a[k-1]+1; i<=n; i++) {
        if(!zt[i]) {
            zt[i]=1;
            a[k]=i;
            sousuo(k+1);
            zt[i]=0;
        }
    }
}
bool cmp(node a,node b) {
    if(a.x<b.x) {
        return true;
    }
    if(a.x==b.x&&a.y<b.y) {
        return true;
    }
    return false;
}
bool Cmp(node a,node b) {
    if(a.y<b.y) {
        return true;
    }
    if(a.y==b.y&&a.x<b.x) {
        return true;
    }
    return false;
}
int main() {
    cin>>n>>R;
    for(int i=1; i<=n; i++) {
        cin>>w[i].y>>w[i].x;
    }
    sort(w+1,w+n+1,cmp);
    a[R]=n;
    sousuo(1);
    sort(w+1,w+n+1,Cmp);
    sousuo(1);//两次搜索
    cout<<best;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值