2017年8月8日提高组T1 作业
Description
小A作为一个乖乖好学生,回到家后总是一丝不苟地完成老师布置的作业。
这天,老师给小A布置了n项作业,每一项作业都有截止时间di和价值vi(你可以理解成每做完一份作业就要快递过去给老师,且快递是不耗费时间的),每完成一项作业便可获得其价值。但小A发现,自己每一个单位时间内只能完成其中的一项作业,请你告诉小A,他最多可以获得多少价值。
Input
第一行有一个正整数n,表示作业的数量。
接下来n行,每行两个正整数表示di和vi。
Output
输出一行,表示小A最多可以获得的价值。
分析:考虑按时间从小到大排序后,依次把价值加入一个小根堆里,如果第i个作业的结束时间早于当前时间并且价值比堆顶价值小,显然就不用加入堆,最后堆里所有元素的价值和就是ans。
代码
#include <cstdio>
#include <queue>
#include <algorithm>
#define maxn 200000
using namespace std;
priority_queue<int,vector<int>,greater<int> >h;
struct arr
{
int t,v;
}a[maxn];
int n;
long long ans;
int so(arr x,arr y)
{
return x.t<y.t;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d%d",&a[i].t,&a[i].v);
sort(a+1,a+n+1,so);
int t1=0;
for (int i=1;i<=n;i++)
{
if (a[i].t>t1)
{
h.push(a[i].v);
t1++;
continue;
}
int p=h.top();
if (p<a[i].v)
{
h.pop();
h.push(a[i].v);
}
}
while (!h.empty())
{
int p=h.top();
ans+=p;
h.pop();
}
printf("%lld",ans);
}