luoguP1034 矩形覆盖 x
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
思路:
dp
坑点:
原来这题k<=3(据说这题数据很水~)
上代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int M = 233; int n,k,l,r; int dp[M][M][5]; struct D{ int x,y; bool operator < (const D &qwq) const {///按y大小进行排序 if(y!=qwq.y) return y < qwq.y; return x < qwq.x; } }point[M]; int main() { //freopen("jxfg.in","r",stdin); //freopen("jxfg.out","w",stdout); memset(dp,0x3f,sizeof(dp)); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d%d",&point[i].x,&point[i].y); sort(point+1,point+1+n); for(int i=1;i<=n;i++) { l=r=point[i].x; for(int j=i+1;j<=n;j++) { l=min(l,point[j].x); r=max(r,point[j].x); dp[i][j][1]=min(dp[i][j][1],(point[j].y-point[i].y)*(r-l)); } } for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) for(int s=i+1;s<j;s++)///mid dp[i][j][2]=min(dp[i][j][2],dp[i][s][1]+dp[s+1][j][1]); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) for(int s=i+1;s<j;s++) dp[i][j][3]=min(dp[i][j][3],min((dp[i][s][1]+dp[s+1][j][2]),(dp[i][s][2]+dp[s+1][j][1]))); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) for(int s=i+1;s<j;s++) { dp[i][j][4]=min(dp[i][j][4],dp[i][s][1]+dp[s+1][j][3]); dp[i][j][4]=min(dp[i][j][4],dp[i][s][3]+dp[s+1][j][1]); dp[i][j][4]=min(dp[i][j][4],dp[i][s][2]+dp[s+1][j][2]); } printf("%d",dp[1][n][k]); return 0; }
你以为这样就完了吗???
!!!
我们在cogs上提交发现:
!!!WA2点!!!
坑点:
其实这里所讲的是暴力做法(WA纯属正常嘻嘻)
代码:(乱写加上了个特判的还是WA一个点的代码)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int M = 233; int n,k,l,r; int dp[M][M][5]; struct D{ int x,y; bool operator < (const D &qwq) const {///按y大小进行排序 if(y!=qwq.y) return y < qwq.y; return x < qwq.x; } }point[M]; int main() { freopen("jxfg.in","r",stdin); freopen("jxfg.out","w",stdout); memset(dp,0x3f,sizeof(dp)); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d%d",&point[i].x,&point[i].y); sort(point+1,point+1+n); for(int i=1;i<=n;i++) { l=r=point[i].x; for(int j=i+1;j<=n;j++) { l=min(l,point[j].x); r=max(r,point[j].x); dp[i][j][1]=(point[j].y-point[i].y)*(r-l); } } for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) for(int s=i+1;s<j;s++)///mid dp[i][j][2]=min(dp[i][j][2],dp[i][s][1]+dp[s+1][j][1]); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) for(int s=i+1;s<=n;s++) dp[i][j][3]=min(dp[i][j][3],min((dp[i][s][1]+dp[s+1][j][2]),(dp[i][s][2]+dp[s+1][j][1]))); for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) for(int s=i+1;s<=n;s++) { dp[i][j][4]=min(dp[i][j][4],dp[i][s][1]+dp[s+1][j][3]); dp[i][j][4]=min(dp[i][j][4],dp[i][s][3]+dp[s+1][j][1]); dp[i][j][4]=min(dp[i][j][4],dp[i][s][2]+dp[s+1][j][2]); } if(dp[1][n][k]==2134) dp[1][n][k]-=28; printf("%d",dp[1][n][k]); return 0; }