P4766 [CERC2014]Outer space invaders

区间 DP。

首先考虑离散化,因为时间跨度比较大,而且我们只考虑时间的先后顺序问题。

然后设计 DP 方案。

f[i][j]f[i][j] 表示 杀死所有出现时间在区间 [i,j][i,j] 内的所有外星人所需的最低代价。

如果区间 [i,j][i,j] 内没有外星人,那么 f[i][j]=0f[i][j]=0

如果有,那么考虑将区间分割为 [i,k1],{k},[k+1,j][i,k-1],\{k\},[k+1,j]

这样就有 f[i][j]=mink=ij{f[i][k1]+f[k+1][j]+maxp,[ap,bp][i,j]dp}f[i][j]=\min\limits_{k=i}^j\{f[i][k-1]+f[k+1][j]+\max\limits_{p,[a_p,b_p]\in[i,j]}d_p\}

然后 maxp,[ap,bp][i,j]dp\max\limits_{p,[a_p,b_p]\in[i,j]}d_p 需要预处理一下,没了

#include <bits/stdc++.h>
#define ll long long
#define inl inline
#define rep(i,a,b) for(int i=(a),i##end=(b);i<=i##end;++i)
#define pre(i,a,b) for(int i=(a),i##end=(b);i>=i##end;--i)
using namespace std;
const int N=310;
int t[N<<1],f[N<<1][N<<1],maxn[N<<1],cnt;
struct Node{
	int a,b,d;
}a[N];
map<int,int>mp;
signed main(void){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--){
		mp.clear();cnt=0;
		int n;cin>>n;
		rep(i,1,n)cin>>a[i].a>>a[i].b>>a[i].d,t[++cnt]=a[i].a,t[++cnt]=a[i].b;
		sort(t+1,t+cnt+1);
		int tm=0;
		rep(i,1,cnt)mp[t[i]]=++tm;
		rep(i,1,n)a[i].a=mp[a[i].a],a[i].b=mp[a[i].b];
		rep(i,1,n)rep(j,a[i].a,a[i].b)maxn[j]=max(maxn[j],a[i].d);
		rep(l,1,tm)rep(i,1,tm-l){
			int j=i+l,r=0,id=0;f[i][j]=0x3f3f3f3f;
			rep(k,1,n)if(a[k].a>=i&&a[k].b<=j&&r<a[k].d)r=a[k].d,id=k;
			if(!r){f[i][j]=0;continue;}
			rep(k,a[id].a,a[id].b)f[i][j]=min(f[i][j],f[i][k-1]+f[k+1][j]+a[id].d);
		}
		cout<<f[1][tm]<<'\n';
	}
}