洛谷1034 NOIP2002 矩形覆盖
问题描述
在平面上有 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。各个矩形必须完全分开(边线与顶点也都不能重合)。
从黄学长那里看到这道题说是k<=4 实际上 k最大是3
所以简单的区间dp就可以过
#include<bits/stdc++.h> using namespace std; int f[55][55][5]; struct node{ int x,y; }a[55]; int n,k,l,r; bool cmp(node a,node b){ if(a.y==b.y)return a.x<b.x; return a.y<b.y; } int main(){ memset(f,127/3,sizeof f); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++){ scanf("%d%d",&a[i].x,&a[i].y); } sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++){ l=r=a[i].x; for(int j=i;j<=n;j++){ l=min(l,a[j].x);r=max(r,a[j].x); f[i][j][1]=(a[j].y-a[i].y)*(r-l); } } for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) for(int q=i;q<j;q++){ f[i][j][2]=min(f[i][j][2],f[i][q][1]+f[q+1][j][1]); } for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) for(int q=i;q<j;q++){ f[i][j][3]=min(f[i][j][3],f[i][q][1]+f[q+1][j][2]); f[i][j][3]=min(f[i][j][3],f[i][q][2]+f[q+1][j][1]); } printf("%d",f[1][n][k]); return 0; }