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);
}