https://www.luogu.org/problem/show?pid=1034
题目描述
在平面上有 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
回溯+剪枝
搜索每个点,每次更新出矩阵的大小,当有矩阵彼此覆盖时,当前方案不可行、
1 #include <algorithm> 2 #include <cstdio> 3 4 inline void read(int &x) 5 { 6 x=0; register char ch=getchar(); 7 for(; ch>'9'||ch<'0'; ) ch=getchar(); 8 for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0'; 9 } 10 const int N(520); 11 int n,k,x[55],y[55]; 12 int ans=0x3f3f3f3f; 13 struct Matrix { 14 int x1,y1,x2,y2; 15 bool use; 16 Matrix() { use=0; } 17 }matrix[55]; 18 19 #define max(a,b) (a>b?a:b) 20 #define min(a,b) (a<b?a:b) 21 inline bool _if(int x,int y,Matrix a) 22 { 23 return x>=a.x1&&x<=a.x2&&y>=a.y1&&y<=a.y2; 24 } 25 inline bool if_(Matrix a,Matrix b) 26 { 27 if(_if(a.x1,a.y1,b)) return true; 28 if(_if(a.x2,a.y1,b)) return true; 29 if(_if(a.x1,a.y2,b)) return true; 30 if(_if(a.x2,a.y2,b)) return true; 31 return false; 32 } 33 void DFS(int now) 34 { 35 Matrix tmp; int sum=0; 36 for(int i=1; i<=k; ++i) 37 { 38 if(!matrix[i].use) continue; 39 sum+=(matrix[i].x2-matrix[i].x1)* 40 (matrix[i].y2-matrix[i].y1); 41 for(int j=i+1; j<=k; ++j) 42 if(matrix[j].use&&if_(matrix[i],matrix[j])) return ; 43 } 44 if(sum>ans) return ; 45 if(now>n) { ans=sum; return ; } 46 for(int i=1; i<=k; ++i) 47 { 48 tmp=matrix[i]; 49 if(!matrix[i].use) 50 { 51 matrix[i].use=1; 52 matrix[i].x1=matrix[i].x2=x[now]; 53 matrix[i].y1=matrix[i].y2=y[now]; 54 } 55 else 56 { 57 matrix[i].x1=min(matrix[i].x1,x[now]); 58 matrix[i].x2=max(matrix[i].x2,x[now]); 59 matrix[i].y1=min(matrix[i].y1,y[now]); 60 matrix[i].y2=max(matrix[i].y2,y[now]); 61 } 62 DFS(now+1); matrix[i]=tmp; 63 } return ; 64 } 65 66 int Presist() 67 { 68 read(n);read(k); 69 for(int i=1; i<=n; ++i) 70 read(x[i]),read(y[i]); 71 DFS(1); printf("%d ",ans); 72 return 0; 73 } 74 75 int Aptal=Presist(); 76 int main(){;}