来自外太空的外星人(最终)入侵了地球。保卫自己,或者解体,被他们同化,或者成为食物。迄今为止,我们无法确定。
外星人遵循已知的攻击模式。有 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 1≤n≤300)。
接下来 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 i−th 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(1≤n≤300). Of the next n n n lines, the i − t h i-th i−th 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,(1≤ai<bi≤10000,1≤di≤10000).
The i − t h i-th i−th 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
3
1 4 4
4 7 5
3 4 7
7
外星人入侵地球,你需要使用一种区域冲击波器来消灭所有外星人。每个外星人有一个出现时间 (a_i)、一个必须被消灭的时间 (b_i) 以及一个距离 (d_i)。你的冲击波器可以设置一个功率 (R),它会瞬间消灭所有距离小于等于 (R) 的外星人,并消耗 (R) 单位的燃料电池。目标是找到消灭所有外星人的最小燃料电池消耗。
这道题可以使用动态规划(DP)来解决。我们需要找到在时间区间内消灭所有外星人的最小成本。具体思路如下:
时间离散化:由于时间点可能很多,我们首先将所有时间点离散化,即将所有 ( a i a_i ai) 和 ( b i b_i bi) 映射到一个连续的整数区间上。
动态规划状态定义:定义 ( d p [ l ] [ r ] dp[l][r] dp[l][r]) 表示在时间区间 ([l, r]) 内消灭所有外星人的最小成本。
状态转移:对于每个时间区间 ([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][k−1]+dp[k+1][r]+di)
其中 ( d i d_i di) 是当前区间内距离最远的外星人的距离。
初始化:如果某个区间内没有外星人,则 ( d p [ l ] [ r ] dp[l][r] dp[l][r] = 0)。
最终答案:( 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();
}
}
输入处理:首先读取外星人的数量 (n),然后读取每个外星人的出现时间 (a_i)、消灭时间 (b_i) 和距离 (d_i)。
时间离散化:将所有时间点 (a_i) 和 (b_i) 存入数组 times
,排序后使用 id
数组进行离散化映射。
动态规划求解:
dp
数组为无穷大。dp[l][r]
的值。输出结果:对于每个测试用例,输出 dp[1][cnt]
,即整个时间区间内的最小成本。
这道题通过动态规划和离散化时间点的方法,有效地解决了在时间区间内消灭所有外星人的最小成本问题。代码实现中需要注意时间点的离散化和状态转移的正确性。