BZOJ4048/3928 [Cerc2014] Outer space invaders

容易发现对于距离你最远的那个外星人,你一定是要在某个时间打他一发的,并且这一发可以顺便带走出现时间区间包含了你打这个时间的其他外星人

那么我们离散化一下,然后考虑区间DP

f[i][j]表示把出现时间>i,消失时间

为什么不是出现时间>=i,消失时间<=j呢,因为这么设的话会出现转移的时候调用自身的情况,就挂了

那么找到这些外星人里距离最远的,然后枚举在哪个时间打这个外星人,f[i][j]=min(f[i][k]+f[k][j]+d[x]),d[x]为最远的外星人和你的距离

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAXN 1010
#define MAXM 1010
#define ll long long
#define eps 1e-8
#define MOD 1000000007
#define INF 1000000000
int n;
int l[MAXN],r[MAXN],v[MAXN];
int f[MAXN][MAXN];
int tls[MAXN],tln,mx;
maph;
int main(){
	int i,j,k,x,y;
	int tmp;
	scanf("%d",&tmp);
	while(tmp--){
		h.clear();
		mx=0;
		tln=0;
		scanf("%d",&n);
		for(i=1;i<=n;i++){
			scanf("%d%d%d",&l[i],&r[i],&v[i]);
			tls[++tln]=l[i];
			tls[++tln]=r[i];
		}
		sort(tls+1,tls+tln+1);
		for(i=1;i<=tln;i++){
			if(tls[i]!=tls[i-1]||i==1){
				h[tls[i]]=++mx;
			}
		}
		for(i=1;i<=n;i++){
			l[i]=h[l[i]];
			r[i]=h[r[i]];
		}
		mx++;
		for(i=1;i<=mx+1;i++){
			for(j=0;j+i-1<=mx;j++){
				f[i][j]=INF;
				int L=j,R=j+i-1;
				x=0;
				for(k=1;k<=n;k++){
					if(l[k]>L&&r[k]v[x]){
						x=k;
					}
				}
				if(!x){
					f[i][j]=0;
					continue ;
				}
				for(k=l[x];k<=r[x];k++){
					f[i][j]=min(f[i][j],f[k-L+1][j]+f[R-k+1][k]+v[x]);
				}
			}
		}
		printf("%d\n",f[mx+1][0]);
	}
	return 0;
}

/*
1
3
1 4 4
4 7 5
3 4 7

*/


你可能感兴趣的:(BZOJ,DP,递推)