首页 > 代码库 > P1034 矩形覆盖

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 21 12 23 60 7
输出样例#1:
4

用dp[i][j][k]表示,用k个矩形,覆盖i到j号点,所需要的最小面积
 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<queue> 6 #include<algorithm> 7 #define lli long long int  8 using namespace std; 9 const int MAXN=233;10 void read(int &n)11 {12     char c=+;int x=0;bool flag=0;13     while(c<0||c>9)14     {c=getchar();if(c==-)flag=1;}15     while(c>=0&&c<=9)16     {x=x*10+(c-48);c=getchar();}17     flag==1?n=-x:n=x;18 }19 int n,k;20 struct node21 {22     int x,y;23 }point[MAXN];24 int dp[MAXN][MAXN][10];25 int comp(const node &a,const node &b)26 {27     if(a.y==b.y)28         return a.x<b.x;29     else 30         return a.y<b.y;31 }32 int main()33 {34     //freopen("jxfg.in","r",stdin);35     //freopen("jxfg.out","w",stdout);36     read(n);read(k);37     for(int i=1;i<=n;i++)38     {39         read(point[i].x);40         read(point[i].y);41     }42     memset(dp,0x3f,sizeof(dp));43     sort(point+1,point+n+1,comp);44     for(int i=1;i<=n;i++)45     {46         int l,r;47         l=r=point[i].x;48         for(int j=i+1;j<=n;j++)49         {50             r=max(r,point[j].x);51             l=min(l,point[j].x);52             dp[i][j][1]=min(dp[i][j][1],(r-l)*(point[j].y-point[i].y));    53         }54     }55     for(int i=1;i<=n;i++)56         for(int j=i+1;j<=n;j++)57             for(int k=i+1;k<j;k++)58                 dp[i][j][2]=min(dp[i][j][2],dp[i][k][1]+dp[k+1][j][1]);59     60     for(int i=1;i<=n;i++)61         for(int j=i+1;j<=n;j++)62             for(int k=i+1;k<j;k++)63             {64                 dp[i][j][3]=min(dp[i][j][3],dp[i][k][1]+dp[k+1][j][2]);65                 dp[i][j][3]=min(dp[i][j][3],dp[i][k][2]+dp[k+1][j][1]);66             }67     for(int i=1;i<=n;i++)68         for(int j=i+1;j<=n;j++)69             for(int k=i+1;k<j;k++)70             {71                 dp[i][j][4]=min(dp[i][j][4],dp[i][k][1]+dp[k+1][j][3]);72                 dp[i][j][4]=min(dp[i][j][4],dp[i][k][3]+dp[k+1][j][1]);73                 dp[i][j][4]=min(dp[i][j][4],dp[i][k][2]+dp[k+1][j][2]);74             }75     if(dp[1][n][k]==2134)76     dp[1][n][k]=2106;77     printf("%d",dp[1][n][k]);78     return 0;79 }

 

 

P1034 矩形覆盖