• [NOIP2002] 提高组 洛谷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

     

    搜索。这题剪枝方法似乎多种多样。

    这份代码的做法:

    将读入的坐标按x和y从小到大排序,然后搜索将连续的i个点分在一起,期间判断问题是否可行,以及进行各种小优化。

     1 /*By SilverN*/
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cmath>
     7 using namespace std;
     8 int read(){
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 struct point{
    15     int x,y;
    16 }a[60];
    17 int cmp(point a,point b){
    18     if(a.x==b.x)return a.y<b.y;
    19     return a.x<b.x;
    20 }
    21 struct block{
    22     int x1,y1,x2,y2;
    23 }b[5];
    24 int n,k;
    25 int ans=1e9;
    26 void DFS(int pos,int cnt,int smm){
    27     if(pos>n){
    28         ans=min(ans,smm);
    29         return;
    30     }
    31     if(cnt>k)return;
    32     int i,j;
    33     b[cnt].x1=a[pos].x;
    34     b[cnt].x2=a[pos].x;
    35     b[cnt].y1=a[pos].y;
    36     b[cnt].y2=a[pos].y;
    37     for(i=pos;i<=n;i++){
    38         b[cnt].y2=max(b[cnt].y2,a[i].y);
    39         b[cnt].x2=max(b[cnt].x2,a[i].x);
    40         b[cnt].x1=min(b[cnt].x1,a[i].x);
    41         b[cnt].y1=min(b[cnt].y1,a[i].y);
    42         for(j=1;j<cnt;j++){
    43             if(b[cnt].x1<=b[j].x2 && b[cnt].y1<=b[j].y2)return;
    44         }
    45         if(i<n && cnt==k)continue;
    46         DFS(i+1,cnt+1,smm+(b[cnt].x2-b[cnt].x1)*(b[cnt].y2-b[cnt].y1));
    47     }
    48     return;
    49 }
    50 int main(){
    51     n=read();k=read();
    52     int i,j;
    53     for(i=1;i<=n;i++){
    54         a[i].y=read();a[i].x=read();
    55     }
    56     sort(a+1,a+n+1,cmp);
    57     memset(b,-1,sizeof b);
    58     DFS(1,1,0);
    59     printf("%d
    ",ans);
    60     return 0;
    61 }
  • 相关阅读:
    MYSQL查看数据表最后更新时间
    linux在终端模拟软件实现文件上传下载
    yum常用操作
    释放Linux占用端口
    CentOS7.3编译安装MariaDB10.2.6
    CentOS7编译安装Nginx1.10.1
    Linux系统安装ActiveMQ时遇到服务无法启动的问题
    需求分析读书笔记(一)
    实用地址分享
    元素居中汇总
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5970766.html
Copyright © 2020-2023  润新知