1. 程式人生 > >Rectangular Covering [POJ2836] [狀壓DP]

Rectangular Covering [POJ2836] [狀壓DP]

一個 single eof struct sts cst 最小 open rectangle

題意

平面上有 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 x, y (−1,000 ≤ x, y ≤ 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\n", 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

Rectangular Covering [POJ2836] [狀壓DP]