[背景]
5.6进行一场虚伪的测试,很垃圾的成绩让VHOS决定明天开坑写反思。
今天先来说一些高级的东西,优先队列<堆><HEAP>
这个东西ISO C++内附,真是极大的好事。
[题干][#227][USACO 工作安排]
Farmer John 有太多的工作要做啊!!!!!!!!为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间。 他的工作日从0时刻开始,有1000000000个单位时间(!)。在任一时刻,他都可以选择编号1~N的N(1 <= N <= 100000)项工作中的任意一项工作来完成。
因为他在每个单位时间里只能做一个工作,而每项工作又有一个截止日期,所以他很难有时间完成所有N个工作,虽然还是有可能。
对于第i个工作,有一个截止时间D_i(1 <= D_i <= 1000000000),如果他可以完成这个工作,那么他可以获利P_i( 1<=P_i<=1000000000 ).
在给定的工作利润和截止时间下,FJ能够获得的利润最大为多少呢?答案可能会超过32位整型。
输入格式
第1行:一个整数N. 第2~N+1行:第i+1行有两个用空格分开的整数:D_i和P_i.
输出格式
输出一行,里面有一个整数,表示最大获利值。
[分析]
作为一个虚伪的信息题,第一感觉暴力搜索绝对不可以[滑稽] :
当然要用堆啊!
首先,我们分析一下这道题目,很显然是贪心题,但怎么贪呢?
就是用一个小顶堆存储最贱的工作...然后就一点一点的填充下去,一旦出现BUG,就是时间不够,就把最补偿小的那个工作顶替掉;
然后皮一波
然后是核心程序
就是弹出最小的东西....
#include<cstdio>
#include<cctype>
#include<queue>
#include<algorithm>
#pragma GCC optimize("O3")
typedef long long int64;
const int max_size=1e5+1;
struct node
{
int value;
int time;
friend bool operator<(node x,node y)
{
return x.time<y.time;
}
}tasks[max_size]={};
inline int ip_int(void)
{
register bool sign=false;
register char ip_int='#';
while(!isdigit(ip_int=getchar()))
sign|=(ip_int=='-');
register int op=(ip_int^'0');
while(isdigit(ip_int=getchar()))
op=(op<<3)+(op<<1)+(ip_int^'0');
return sign?~op+1:op;
}
int task=0;
std::priority_queue<int,std::vector<int>,std::greater<int> >heap;
void input(void)
{
task=ip_int();
for(int i=1;i<=task;i++)
{
tasks[i].time=ip_int();
tasks[i].value=ip_int();
}
return;
}
void work(void)
{
int64 answer=0;
std::sort(tasks+1,tasks+task+1);
int tmp_time=0;
for(int i=1;i<=task;i++)
{
heap.push(tasks[i].value);
answer+=tasks[i].value;
if(++tmp_time>tasks[i].time)
{
answer-=heap.top();
heap.pop();
tmp_time--;
}
}
printf("%lld\n",answer);
return;
}
int main(void)
{
input();
work();
return 0;
}