Cover

Time Limit: 1000MS Memory Limit: 65536K

You are given ​N points in the coordinate system. They need to be covered with one or more rectangles, such that the following conditions are met:
● The sides of each rectangle are parallel with the coordinate axes,
● The center of each rectangle is in the origin, i.e. point (0, 0),
● Each given point is located either inside of the rectangle or on its boundaries.
Of course, it is possible to cover all the points using only one rectangle, but this rectangle could have a very large surface area. Our goal is to find a selection of required rectangles such that the sum of their surface areas is minimal

Input

The first line of input contains the integer ​N ​ (1 ≤ ​N ​ ≤ 5000), the number of points.
Each of the following ​N lines contains two integers ​X and ​Y (-50 000 000 ≤ ​X, Y ≤ 50 000 000, ​XY ​ ≠ 0), the coordinates of each point
###Output
You must output the required minimal sum of surface areas of the rectangles.

Sample Input

2
1 1
-1 -1

3
-7 19
9 -30
25 10

6
1 20
3 17
5 15
8 12
9 11
10 10

Sample Output

4
2080
760


题意:

在坐标系中
定义矩形是以原点为中心的。
给出n个点,
让矩形覆盖点,即点在矩形内部或边缘上
可用任意个矩形,求这些矩形的最小面积和


题解:

这些矩形可互相叠加,重复部分面积时要计算的,所以时矩形面积变小的方法就是让一些点公用一个矩形。
输入预处理:
将所有的点排序,若以某个点为一个矩形的顶点时,把这个矩形可以覆盖的点都删去。O(N2)O(N^2)
然后对于剩下的点dp,开一维数组dp[5005]
dp[i]表示更新到第i个点时的最小面积
初始化dp[i]为合并第一个点到第i个点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
class point : public pair<ll, ll>
{
public:
point() {}
inline point(ll x, ll y)
{
first = x;second = y;
}
inline constexpr ll get_area()
{
return first * second;
}
inline point operator -(const point&b)const
{
return point(abs(first - b.first), abs(second - b.second));
}
inline point merge(const point&b)const
{
return point(max(first, b.first), max(second, b.second));
}
};
vector<point>v, s;
ll dp[5050];
int main()
{
int N;
v.clear();
scanf("%d", &N);
for (int i = 0; i < N; i++)
{
ll a, b;
scanf("%lld%lld", &a, &b);
v.push_back(point(abs(a), abs(b)));
}
sort(v.begin(), v.end());
for (int i = 0; i < v.size(); i++)
{
for (int j = i + 1; j < v.size(); j++)
{
if (v[j].first >= v[i].first&&v[j].second >= v[i].second)
{
v[i] = point(0, 0);
}
}
}
sort(v.begin(), v.end());
s.clear();
s.insert(s.begin(), upper_bound(v.begin(), v.end(), point(0, 0)), v.end());
for (int i = 0; i < s.size(); i++)
{
dp[i] = (s[0].merge(s[i])).get_area();
}
for (int i = 0; i < s.size(); i++)
{
for (int j = i + 1; j < s.size(); j++)
{
dp[j] = min(dp[j], dp[i] + (s[i + 1].merge(s[j])).get_area());
}
}
printf("%lld\n", dp[s.size() - 1] * 4);
}