Rectangular Covering
题解:先预处理出所有的矩形吧。然后将每个矩形所涵盖的点也处理出来。最后再
d
p
dp
dp。
d
p
[
s
]
dp[s]
dp[s]表示矩形集合为
s
s
s的时候的最小面积。则有
d
p
[
s
∣
j
]
=
m
i
n
(
d
p
[
s
∣
j
]
,
d
p
[
s
]
+
a
[
j
]
.
a
r
e
a
)
dp[s|j] = min(dp[s|j],dp[s] + a[j].area)
dp[s∣j]=min(dp[s∣j],dp[s]+a[j].area)。
代码
#include<iostream>
#include<cstring>
using namespace std;
struct node {
int id, area;
node() {}
node(int _id,int _area ) : id(_id), area(_area) {}
}a[300];
int dp[1 << 16], n;
pair<int,int> p[20];
bool fun(int i,int j,int k)
{
return ((p[i].first - p[k].first) * (p[j].first - p[k].first) <= 0 && ((p[i].second - p[k].second) * (p[j].second - p[k].second) <= 0));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
while(cin >> n, n) {
int x,y;
for(int i = 0; i < n; ++i) {
cin >> x >> y;
p[i] = make_pair(x,y);
}
node t;
int cnt = 0;
for(int i = 0; i < n; ++i) {
for(int j = i + 1; j < n; ++j) {
t.id = 0;
t.area = max(1,abs(p[i].first - p[j].first)) * max(1,abs(p[i].second - p[j].second));
t.id |= 1 << i;
t.id |= 1 << j;
for(int k = 0; k < n; ++k) {
if(fun(i,j,k)) {
t.id |= 1 << k;
}
}
a[cnt++] = t;
}
}
memset(dp, 0x3f, sizeof dp);
dp[0] = 0;
for(int i = 0; i < cnt; ++i) {
for(int j = 0; j < (1 << n); ++j) {
dp[j | a[i].id] = min(dp[j | a[i].id], dp[j] + a[i].area);
}
}
cout << dp[(1 << n) -1] << endl;
}
return 0;
}