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;
}
posted @ 2019-10-20 22:29  wuhan2005  阅读(98)  评论(0编辑  收藏  举报