Cover Point (DP)

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个点

#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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
- `ignore_bins`: 在覆盖点设计,可能存在一些不想被覆盖的点,例如非常不常见的错误或异常情况。`ignore_bins` 可以用于指定不需要覆盖的点或区域,这些点或区域将被忽略。 在实现上,可以将 `ignore_bins` 指定的点或区域所对应的计数值设置为 0。这样,在计算覆盖率时,这些点或区域将被认为是已被覆盖的,从而提高了测试的覆盖率。 - `binsof`: 在覆盖点设计,有时候需要对不同的输入或情况进行区分,例如测试一个函数在接收不同参数时的行为是否正确。`binsof` 可以用于按照输入或情况将覆盖点进行分类。 在实现上,可以将每个覆盖点与对应的输入或情况进行关联,例如使用一个字典来记录每个覆盖点所属的输入或情况。这样,在计算覆盖率时,可以按照不同的输入或情况分别统计覆盖率,从而更好地了解被测试代码的行为。 - `intersect`: 在覆盖点设计,有些点可能会被多个条件覆盖,例如一个 if 语句包含多个条件,而这些条件分别覆盖了不同的点。`intersect` 可以用于指定多个条件覆盖同一个点时,需要同时满足哪些条件才算作覆盖。 在实现上,可以将每个覆盖点与对应的条件进行关联,并使用逻辑运算符(如 AND、OR)来判断是否满足多个条件。例如,对于一个包含多个条件的 if 语句,可以使用 AND 运算符来表示同时满足所有条件时才算作覆盖。这样,在计算覆盖率时,只有同时满足所有条件的点才会被认为是已被覆盖的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值