2034: [2009國家集訓隊]最大收益

Description

給出N件單位時間任務,對於第i件任務,如果要完成該任務,需要佔用[Si, Ti]間的某個時刻,且完成後會有Vi的收益。求最大收益。 N≤5000,1 ≤ Si ≤ Ti ≤ 108,1 ≤ Vi ≤ 108。 澄清:一個時刻只能做一件任務,做一個任務也只需要一個時刻。

題解:

看到題目後就開始亂想貪心,然而啥都沒想出來。

FQW師兄的題解講得很詳細了:戳這裏

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=5010;
int n;
struct node{
	int x,y,z,k;
}sa[N];
bool cmp1(node x,node y)
{
	return x.x<y.x;
}
bool cmp2(node x,node y)
{
	return x.z>y.z;
}
int match[N];
int pos[N];
bool check(int k,int x)
{
	if(pos[x]>sa[k].y) return false;
	if(!match[x])
	{
		match[x]=k;
		return true;
	}
	int yu=match[x];
	if(sa[k].y>sa[yu].y) return check(k,x+1);
	else 
	{
		if(check(yu,x+1))
		{
			match[x]=k;
			return true;
		}
	}
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d%d%d",&sa[i].x,&sa[i].y,&sa[i].z);
	sort(sa+1,sa+1+n,cmp1);
	for(int i=1;i<=n;i++) pos[i]=max(pos[i-1]+1,sa[i].x);
	for(int i=1;i<=n;i++)
	{
		sa[i].k=sa[i-1].k;
		while(pos[sa[i].k]<sa[i].x&&sa[i].k<n) sa[i].k++;
	}
	sort(sa+1,sa+1+n,cmp2);
	long long ans=0;
	for(int i=1;i<=n;i++)
	if(check(i,sa[i].k)) ans+=sa[i].z;
	printf("%lld",ans);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章