题目大意:
n 台计算机,第 i台计算机的运算能力为 vi。
任务分配:第 i个任务在 ai时刻分配,指定计算机编号为bi,耗时为 ci ,算力消耗为 di。
如果此任务成功分配,将立刻开始运行,期间持续占用 bi号计算机 di的算力,持续 ci秒。
对于每次任务分配,如果计算机剩余的运算能力不足则输出 −1,并取消这次分配,否则输出分配完这个任务后这台计算机的剩余运算能力。
输入样例:
2 6 5 5 1 1 5 3 2 2 2 6 3 1 2 3 4 1 6 1 5 1 3 3 6 1 3 4
输出样例:
2 -1 -1 1 -1 0
样例解释
时刻 1,第 1 个任务被分配到第 1台计算机,耗时为 5,这个任务时刻 6 会结束,占用计算机 1 的算力 3。
时刻 2,第 2个任务需要的算力不足,所以分配失败了。
时刻 3,第 1个计算机仍然正在计算第 1个任务,剩余算力不足 3,所以失败。
时刻 4,第 1个计算机仍然正在计算第 1个任务,但剩余算力足够,分配后剩余算力1。
时刻 5,第 1个计算机仍然正在计算第 1,4个任务,剩余算力不足 4 失败。
时刻 6,第 1个计算机仍然正在计算第 4 个任务,剩余算力足够,且恰好用完。
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cstdlib>
using namespace std;
int s[200200];
typedef pair<int,int> PII;//装入结束时刻和剩余算力
priority_queue<PII,vector<PII>,greater<PII> > pq[200200]; //小根堆,记录每台计算机的任务
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&s[i]);//i台计算机的算力(cpu)
while(m--)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
while(pq[b].size()&&pq[b].top().first<=a)//当它不为空的时候并且小根堆的顶端值的结束时刻要在新一轮开始之前结束
{
s[b]+=pq[b].top().second;//恢复算力
pq[b].pop();//把任务弹出
}
if(s[b]<d) printf("-1\n");//如果当前算力无法满足它的要求,则输出-1
else
{
pq[b].push({a+c,d});//加入任务:当它为空的时候把任务放进去,比如首位置的结束时间跟算力
s[b]-=d;//减去计算机相应的算力
printf("%d\n",s[b]);
}
}
return 0;
}
_________知识分割线_________
priority_queue<Type,Container,Functional>
<> 中分别为 数据类型,容器类型(vector,deque......),比较方式
priority_queue<int,vector<int>,greater<int> > pq[] //小根堆
priority_queue<int,vector<int>,less<int> > //大根堆
//默认是大根堆
pair的比较
先比较第一个元素。第一个元素相等时再比较第二个元素
(2,5)>(1,3)>(1,2)