zoukankan      html  css  js  c++  java
  • Rectangular Covering [POJ2836] [状压DP]

    题意

    平面上有 n (2 ≤ n ≤ 15) 个点,现用平行于坐标轴的矩形去覆盖所有点,每个矩形至少盖两个点,矩形面积不可为0,求这些矩形的最小面积。

    Input

    The input consists of several test cases. Each test cases begins with a line containing a single integer n (2 ≤ n ≤ 15). Each of the next n lines contains two integers xy (−1,000 ≤ xy ≤ 1,000) giving the coordinates of a point. It is assumed that no two points are the same as each other. A single zero follows the last test case.

    Output

    Output the minimum total area of rectangles on a separate line for each test case.

    Sample Input

    2
    0 1
    1 0
    0

    Sample Output

    1

    Analysis

    枚举两个个点,再算包含在这两个点的点,算进一个矩形

    然后在枚举矩形,进行状压DP

    Code

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <vector>
      5  
      6 using std::vector;
      7 using std::min;
      8 using std::max;
      9  
     10 const int MAXN = 15;
     11 const int INF = 0x3f3f3f3f;
     12  
     13 struct POINT
     14 {
     15     int x;
     16     int y;
     17 } p[MAXN + 1];
     18  
     19 struct RECTANGLE
     20 {
     21     int area;
     22     int cover;
     23 } r[MAXN * MAXN];
     24  
     25 int n;
     26 int dp[1 << MAXN];
     27 int area[MAXN + 1][MAXN + 1];
     28 int cnt;
     29  
     30 int abs(int x)
     31 {
     32     return x > 0 ? x : -x;
     33 }
     34  
     35 void Read()
     36 {
     37     for (int i = 0; i < n; ++i)
     38     {
     39         scanf("%d%d", &p[i].x, &p[i].y);
     40     }
     41 }
     42  
     43 void Init()
     44 {
     45     cnt = 0;
     46     for (int i = 0; i < n; ++i)
     47     {
     48         for (int j = 0; j < i; ++j)
     49         {
     50             if (j != i)
     51             {
     52                 int width = abs(p[i].x - p[j].x) == 0 ? 1 : abs(p[i].x - p[j].x);
     53                 int height = abs(p[i].y - p[j].y) == 0 ? 1 : abs(p[i].y - p[j].y);
     54                 r[cnt].area = width * height;
     55                 r[cnt].cover = 0;
     56                 for (int k = 0; k < n; ++k)
     57                 {
     58                     if (p[k].x >= min(p[i].x, p[j].x) && p[k].x <= max(p[i].x, p[j].x) &&
     59                             p[k].y >= min(p[i].y, p[j].y) && p[k].y <= max(p[i].y, p[j].y))
     60                     {
     61                         r[cnt].cover |= (1 << k);
     62                     }
     63                 }
     64                 ++cnt;
     65             }
     66         }
     67     }
     68 }
     69  
     70 void Dp()
     71 {
     72     memset(dp, 0x3f, sizeof(dp));
     73     dp[0] = 0;
     74     for (int S = 0; S < (1 << n); ++S)
     75     {
     76         if (dp[S] != INF)
     77         {
     78             for (int i = 0; i < cnt; ++i)
     79             {
     80                 int news = S | r[i].cover;
     81                 if (news != S)
     82                 {
     83                     dp[news] = min(dp[news], dp[S] + r[i].area);
     84                 }
     85             }
     86         }
     87     }
     88     printf("%d
    ", dp[(1 << n) - 1]);
     89 }
     90  
     91 int main()
     92 {
     93     while (scanf("%d", &n) == 1 && n)
     94     {
     95         Read();
     96         Init();
     97         Dp();
     98     }
     99  
    100     return 0;
    101 }
    View Code
  • 相关阅读:
    准备改进回复功能
    今天的任务
    日历已加上
    web.config中globalization设置的问题
    Request获取url信息的各种方法比较
    增加了高级评论功能
    如何修改日历的CSS
    推荐有关MasterPages的三篇文章
    如何定制日历控件显示的星期文字
    FreeTextBox的问题终于解决了
  • 原文地址:https://www.cnblogs.com/ibilllee/p/9314235.html
Copyright © 2011-2022 走看看