822C Hacker, pack your bags!

对我来说非常有启发的一条题目

机票具有往返两个时间点,做不交叉匹配的时候可以把一张机票一分为二,

每张机票按照时间点构造成两个事件,

对总的事件做排序就可以很轻松的做到无交叉匹配

bestCost[i]意思是时长i天的机票最少的花费,由于枚举时间点的缘故必定可行

代码:

#include<bits/stdc++.h>

using namespace std;
#define ll long long

const int maxn=2e5+9;
const int inf=2e9+2;
int n,x,l,r,c;
int bestCost[maxn];

struct CARD{
	int timePoint,len,cost,type;
	int operator<(const CARD &x){
		if(timePoint==x.timePoint)return type<x.type;
		return timePoint<x.timePoint;
	}
}arr[maxn<<1];

int main(){
	scanf("%d%d",&n,&x);
	int cnt=0;
	for(int i=1;i<=n;i++){
		scanf("%d%d%d",&l,&r,&c);
		arr[++cnt]=CARD{l,r-l+1,c,-1};
		arr[++cnt]=CARD{r,r-l+1,c,1};
	}	
	ll ans=inf;
	sort(arr+1,arr+1+cnt);
	fill(bestCost+1,bestCost+x+1,inf);

	for(int i=1;i<=cnt;i++){	//枚举时间点
		if(arr[i].type==-1){	//出发
			if(arr[i].len<x){
				ans=min(ans,1ll*arr[i].cost+bestCost[x-arr[i].len]);
			}
		}else{
			bestCost[arr[i].len]=min(bestCost[arr[i].len],arr[i].cost);
		}
	}
	if(ans>=inf)ans=-1;
	printf("%lld\n",ans);
}
自己的暴力在大数据上有的卡有的过,奥妙重重


posted @ 2017-07-03 16:33  Drenight  阅读(178)  评论(0编辑  收藏  举报