题目链接:工作安排
分析
先把所有工作按截止时间排序,如果时间充足就做,不足就留下利润高的。很显然的贪心。用小根堆维护工作的截止时间和利润。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct lwx
{
int d,p;
}a[100001];
long long n,mx,len,tree[200001];
int cmp(lwx l,lwx r)
{
if(l.d==r.d) return l.p>r.p;
return l.d<r.d;
}
void put(int x)
{
len++;
tree[len]=x;
int son=len;
while(son>1)
{
int fa=son/2;
if(tree[fa]<tree[son])
{
break;
}
else
{
swap(tree[fa],tree[son]);
son=fa;
}
}
}
int get()
{
int t=tree[1];
tree[1]=tree[len];
len--;
int fa=1;
while(fa*2<=len)
{
int son=fa*2;
if(son+1<=len&&tree[son+1]<tree[son])
{
son++;
}
if(tree[son]>tree[fa])
{
break;
}
else
{
swap(tree[son],tree[fa]);
fa=son;
}
}
return t;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].d>>a[i].p;
}
sort(a+1,a+n+1,cmp);
long long sum=0,tot=0;
for(int i=1;i<=n;i++)
{
int k=a[i].d;
put(a[i].p);
sum+=a[i].p;
tot++;//真实用时
if(tot>k)//时间不够
{
int t=get();//小根堆,利润最低在堆顶
sum-=t;
tot--;
}
mx=max(mx,sum);
}
cout<<mx;
return 0;
}