luoguP4766 [CERC2014]Outer space invaders
看到数据范围,外星人出现的时间范围是\(10^4\),而只有300个外星人,显然先对数据进行离散化.
然后我们可以进行区间\(dp\).令\(dp[L][R]\)表示在时间\([L,R]\)内打死所有被区间完全包含的外星人所花费的代价.
首先对于没有包含任何外星人的区间,它的\(dp\)值直接赋为零.
反之,我们贪心的取区间内半径最大的外星人的半径,再枚举这个外星人的限制时段\(k\in[Alien[i].l,Alien[i].r]\).
\[\begin{align}
\therefore dp[L][R]=\max(dp[L][R],dp[L][k-1]+Alien[i].d+dp[k+1][R])
\end{align}
\]
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define il inline
#define rg register
#define gi read<int>
#define pli pair<ll, int>
using namespace std;
typedef long long ll;
const int O = 1010;
struct Data { int a, b, v; } s[O];
template<class TT>
il TT read() {
TT o = 0,fl = 1; char ch = getchar();
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') fl = -1, ch = getchar();
while (isdigit(ch)) o = o * 10 + ch - '0', ch = getchar();
return fl * o;
}
int n, Uni[O << 1], dp[O << 1][O << 1];
int main() {
for (int T = gi(); T--; ) {
n = gi();
for (int i = 1; i <= n; ++i) {
s[i] = (Data) { gi(), gi(), gi() };
Uni[(i << 1) - 1] = s[i].a, Uni[i << 1] = s[i].b;
}
sort(Uni + 1, Uni + n + n + 1);
int sub = unique(Uni + 1, Uni + n + n + 1) - Uni - 1;
for (int i = 1; i <= n; ++i) {
s[i].a = lower_bound(Uni + 1, Uni + sub + 1, s[i].a) - Uni;
s[i].b = lower_bound(Uni + 1, Uni + sub + 1, s[i].b) - Uni;
}
s[0].v = -2e9;
for (int len = 0; len < sub; ++len)
for (int st = 1; st + len <= sub; ++st) {
int ed = st + len, id = 0;
for (int i = 1; i <= n; ++i)
if (st <= s[i].a && s[i].b <= ed && s[id].v < s[i].v)
id = i;
if (!id) { dp[st][ed] = 0; continue; }
dp[st][ed] = 2e9;
for (int i = s[id].a; i <= s[id].b; ++i)
dp[st][ed] = min(dp[st][ed], dp[st][i - 1] + s[id].v + dp[i + 1][ed]);
}
printf("%d\n", dp[1][sub]);
}
return 0;
}