题解 P2949 [USACO09OPEN]工作调度Work Scheduling
Posted point-king
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 P2949 [USACO09OPEN]工作调度Work Scheduling相关的知识,希望对你有一定的参考价值。
这道题的思路很神奇,是一种可以后悔的贪心。
解题思路:
我们先将每一个任务按照限制时间排序。
对于每一种任务,我们有两种抉择:
for(int i=1;i<=n;++i)
{
if(a[i].d<=q.size())//即是当前这个任务在限制时间内无法完成。
{
//那么就在前面找到价值比当前的任务小的价值最小的任务,将其替换。
}
else
{
//直接塞入储存任务的数组
++time_now;
}
}
在上面的思路中,我们需要寻找最小的任务价值,就可以利用优先队列(小根堆),那么上面的思路就整理如下:
for(int i=1;i<=n;++i)
{
if(a[i].d<=q.size())
{
if(a[i].p>q.top().p)
{
ans+=a[i].p-q.top().p;
q.pop();
q.push(a[i]);
}
}
else
{
ans+=a[i].p;
q.push(a[i]);
}
}
完整代码:
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
#define int long long
struct Work
{
int d,p;
bool operator > (const Work a) const
{
return p<a.p;
}
bool operator < (const Work a) const
{
return p>a.p;
}
};
Work a[1000005];
bool cmp(Work a,Work b)
{
return a.d<b.d;
}
priority_queue <Work> q;
int n,ans=0;
signed main()
{
scanf("%lld",&n);
for(int i=1;i<=n;++i)
{
scanf("%lld%lld",&a[i].d,&a[i].p);
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;++i)
{
if(a[i].d<=q.size())
{
if(a[i].p>q.top().p)
{
ans+=a[i].p-q.top().p;
q.pop();
q.push(a[i]);
}
}
else
{
ans+=a[i].p;
q.push(a[i]);
}
}
printf("%lld",ans);
return 0;
}
以上是关于题解 P2949 [USACO09OPEN]工作调度Work Scheduling的主要内容,如果未能解决你的问题,请参考以下文章
luogu P2949 [USACO09OPEN]工作调度Work Scheduling
bzoj1572[Usaco2009 Open]工作安排Job