P4766 [CERC2014] Outer space invaders

P4766 [CERC2014] Outer space invaders

题面翻译

题目描述

来自外太空的外星人(最终)入侵了地球。保卫自己,或者解体,被他们同化,或者成为食物。迄今为止,我们无法确定。

外星人遵循已知的攻击模式。有 N N N 个外星人进攻,第 i i i 个进攻的外星人会在时间 a i a_i ai 出现,距离你的距离为 d i d_i di,它必须在时间 b i b_i bi 前被消灭,否则被消灭的会是你。

你的武器是一个区域冲击波器,可以设置任何给定的功率。如果被设置了功率 R R R,它会瞬间摧毁与你的距离在 R R R 以内的所有外星人(可以等于),同时它也会消耗 R R R 单位的燃料电池。

求摧毁所有外星人的最低成本(消耗多少燃料电池),同时保证自己的生命安全。

输入格式

第一行输入一个数 T T T,表示有 T T T 组数据。

每组数据的第一行为外星人的数量 n n n 1 ≤ n ≤ 300 1\leq n\leq 300 1n300)。

接下来 n n n 行,每行有三个数 a i , b i , d i a_i,b_i,d_i ai,bi,di,表示这个外星人在时间 a i a_i ai 出现,距离你 d i d_i di,在 b i b_i bi 前时刻死亡。

输出格式

T T T 行,每行输出摧毁所有外星人的最低成本。

题目描述

The aliens from outer space have (finally!) invaded Earth. Defend yourself, or be disintegrated!

Or assimilated. Or eaten. We are not yet sure.

The aliens follow a known attack pattern. There are n n n attackers, the i − t h i-th ith one appears at time a i a_i ai, at distance d i d_i di from you. He must be destroyed no later than at time b i b_i bi, or else he will fire his weapon, which will definitely end the fight.

Your weapon is an area-blaster, which can be set to any given power. If fired with power R R R,it momentarily destroys all aliens at distance R R R or smaller. It also consumes R R R fuel cells.

Determine the minimal cost (measured in fuel cells) of destroying all the aliens, without being killed.

输入格式

The first line of input contains the number of test cases T T T. The descriptions of the test cases follow:

Each test case starts with a line containing the number of aliens n ( 1 ≤ n ≤ 300 ) n(1 \le n \le 300) n(1n300). Of the next n n n lines, the i − t h i-th ith one contains three integers a i , b i , d i , ( 1 ≤ a i < b i ≤ 10000 , 1 ≤ d i ≤ 10000 ) a_i, b_i, d_i, (1 \le a_i < b_i \le 10 000, 1 \le d_i \le 10 000) ai,bi,di,(1ai<bi10000,1di10000).

The i − t h i-th ith alien appears at time a i a_i ai, is idle until b i b_i bi, and his distance from you is d i d_i di.

输出格式

For each test case, output one line containing the minimum number of cells needed to destroy all the aliens.

样例 #1

样例输入 #1

1
3
1 4 4
4 7 5
3 4 7

样例输出 #1

7

题目大意

外星人入侵地球,你需要使用一种区域冲击波器来消灭所有外星人。每个外星人有一个出现时间 (a_i)、一个必须被消灭的时间 (b_i) 以及一个距离 (d_i)。你的冲击波器可以设置一个功率 (R),它会瞬间消灭所有距离小于等于 (R) 的外星人,并消耗 (R) 单位的燃料电池。目标是找到消灭所有外星人的最小燃料电池消耗。

题解

这道题可以使用动态规划(DP)来解决。我们需要找到在时间区间内消灭所有外星人的最小成本。具体思路如下:

  1. 时间离散化:由于时间点可能很多,我们首先将所有时间点离散化,即将所有 ( a i a_i ai) 和 ( b i b_i bi) 映射到一个连续的整数区间上。

  2. 动态规划状态定义:定义 ( d p [ l ] [ r ] dp[l][r] dp[l][r]) 表示在时间区间 ([l, r]) 内消灭所有外星人的最小成本。

  3. 状态转移:对于每个时间区间 ([l, r]),我们找到在该区间内距离最远的外星人(即 ( d i d_i di) 最大的外星人),然后枚举在该外星人的时间区间内选择一个时间点 (k) 来发射冲击波。状态转移方程为:
    d p [ l ] [ r ] = min ⁡ ( d p [ l ] [ r ] , d p [ l ] [ k − 1 ] + d p [ k + 1 ] [ r ] + d i ) dp[l][r] = \min(dp[l][r], dp[l][k-1] + dp[k+1][r] + d_i) dp[l][r]=min(dp[l][r],dp[l][k1]+dp[k+1][r]+di)

其中 ( d i d_i di) 是当前区间内距离最远的外星人的距离。

  1. 初始化:如果某个区间内没有外星人,则 ( d p [ l ] [ r ] dp[l][r] dp[l][r] = 0)。

  2. 最终答案:( d p [ 1 ] [ c n t ] dp[1][cnt] dp[1][cnt]),其中 (cnt) 是离散化后的最大时间点。

代码分析

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define endl '\n'
#define int long long
#define Max(a, b) (((a) > (b)) ? (a) : (b))
#define Min(a, b) (((a) < (b)) ? (a) : (b))
#define BoBoowen ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;

const int N = 550 * 2;
const int inf = 1e9;
int n;
int dp[N][N];
int times[N];
int id[N * N];

struct Node
{
    int l;
    int r;
    int d;
} w1[N], w2[N];

void cleared()
{
    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            dp[i][j] = 0;
        }
    }
}

void solved()
{
    cleared();
    cin >> n;

    for (int i = 1; i <= n; i++)
    {
        cin >> w1[i].l >> w1[i].r >> w1[i].d;
    }

    int cnt = 0;
    for (int i = 1; i <= n; ++i)
    {
        times[++cnt] = w1[i].l;
        times[++cnt] = w1[i].r;
    }

    sort(times + 1, times + cnt + 1);

    for (int i = 1; i <= cnt; i++)
    {
        id[times[i]] = i;
    }
    for (int i = 1; i <= n; i++)
    {
        w2[i].l = id[w1[i].l];
        w2[i].r = id[w1[i].r];
        w2[i].d = w1[i].d;
    }

    for (int len = 1; len < cnt; len++)
    {
        for (int l = 1; l + len <= cnt; l++)
        {
            int r = l + len;
            dp[l][r] = inf;
            int maxx = -inf;
            int max_id = 0;
            for (int k = 1; k <= n; k++)
            {
                if (w2[k].l >= l && w2[k].r <= r)
                {
                    if (maxx < w2[k].d || max_id == 0)
                    {
                        max_id = k;
                        maxx = max(maxx, w2[k].d);
                    }
                }
            }
            if (max_id == 0)
            {
                dp[l][r] = 0;
                continue;
            }

            for (int k = w2[max_id].l; k <= w2[max_id].r; k++)
            {
                dp[l][r] = min(dp[l][r], dp[l][k - 1] + dp[k + 1][r] + w2[max_id].d);
            }
        }
    }
    cout << dp[1][cnt] << endl;
}

signed main()
{
    BoBoowen;

    int T = 1;
    cin >> T;
    while (T--)
    {
        solved();
    }
}

代码分析

  1. 输入处理:首先读取外星人的数量 (n),然后读取每个外星人的出现时间 (a_i)、消灭时间 (b_i) 和距离 (d_i)。

  2. 时间离散化:将所有时间点 (a_i) 和 (b_i) 存入数组 times,排序后使用 id 数组进行离散化映射。

  3. 动态规划求解

    • 初始化 dp 数组为无穷大。
    • 对于每个时间区间 ([l, r]),找到该区间内距离最远的外星人。
    • 枚举在该外星人的时间区间内选择一个时间点 (k) 来发射冲击波,更新 dp[l][r] 的值。
  4. 输出结果:对于每个测试用例,输出 dp[1][cnt],即整个时间区间内的最小成本。

总结

这道题通过动态规划和离散化时间点的方法,有效地解决了在时间区间内消灭所有外星人的最小成本问题。代码实现中需要注意时间点的离散化和状态转移的正确性。

你可能感兴趣的:(acm训练集合,区间dp,dp,离散化)