分享

洛谷 P1034 [NOIP2002 T4] 矩形覆盖

 长沙7喜 2018-12-10

 题目描述

在平面上有 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











~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

dfs+剪枝~

对于每个点,枚举新建长方形和加入旧的长方形中两种情况,然后加上剪枝就能过,我的都是1ms左右~

剪枝有:

1.例行剪枝:now>=tot;

2.长方形数大于k;

3.剩余点数小于剩余须加的长方形数;

4.剩余点数等于剩余须加的长方形数,用已有的now值直接更新ans值,因为单个点面积为1;

5.题目中要求的剪枝:不能重合;

另外,第一次把kkz之类的变量设成全局变量,然后就WA40,玄学问题8号……


  1. #include<cstdio>
  2. int n,k,ans,now;
  3. struct node{
  4. int x,y;
  5. }a[51];
  6. struct node1{
  7. int x1,y1,x2,y2;
  8. }c[5];
  9. void add(node1 &u,node v)
  10. {
  11. if(u.x1>v.x) u.x1=v.x;
  12. else if(u.x2<v.x) u.x2=v.x;
  13. if(u.y1>v.y) u.y1=v.y;
  14. else if(u.y2<v.y) u.y2=v.y;
  15. }
  16. bool pd(int u,int v)
  17. {
  18. for(int i=1;i<=v;i++)
  19. if(i!=u)
  20. {
  21. if(c[u].x1>=c[i].x1 && c[u].x1<=c[i].x2 && c[u].y2>=c[i].y1 && c[u].y2<=c[i].y2) return 0;
  22. if(c[u].x1>=c[i].x1 && c[u].x1<=c[i].x2 && c[u].y1>=c[i].y1 && c[u].y1<=c[i].y2) return 0;
  23. if(c[u].x2>=c[i].x1 && c[u].x2<=c[i].x2 && c[u].y2>=c[i].y1 && c[u].y2<=c[i].y2) return 0;
  24. if(c[u].x2>=c[i].x1 && c[u].x2<=c[i].x2 && c[u].y1>=c[i].y1 && c[u].y1<=c[i].y2) return 0;
  25. }
  26. return 1;
  27. }
  28. void dfs(int u,int v)
  29. {
  30. if(now>=ans || v>k || (n-u)<(k-v)) return;
  31. if(u==n)
  32. {
  33. if(v==k) ans=now;return;
  34. }
  35. if(n-u==k-v)
  36. {
  37. ans=now;return;
  38. }
  39. u++;
  40. for(int i=1;i<=v;i++)
  41. {
  42. int kkz=now,kkx1=c[i].x1,kky1=c[i].y1,kkx2=c[i].x2,kky2=c[i].y2;
  43. now-=(c[i].x2-c[i].x1)*(c[i].y2-c[i].y1);add(c[i],a[u]);
  44. now+=(c[i].x2-c[i].x1)*(c[i].y2-c[i].y1);
  45. if(pd(i,v)) dfs(u,v);
  46. now=kkz;c[i].x1=kkx1,c[i].y1=kky1;c[i].x2=kkx2,c[i].y2=kky2;
  47. }
  48. if(v<k)
  49. {
  50. c[++v].x1=c[v].x2=a[u].x;
  51. c[v].y1=c[v].y2=a[u].y;
  52. dfs(u,v);
  53. }
  54. }
  55. int main()
  56. {
  57. scanf("%d%d",&n,&k);ans=999999999;
  58. for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
  59. c[1].x1=c[1].x2=a[1].x;
  60. c[1].y1=c[1].y2=a[1].y;
  61. dfs(1,1);
  62. printf("%d\n",ans);
  63. return 0;
  64. }



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多