Time Limit: 1.0 Seconds Memory Limit: 65536K
Total Runs: 130 Accepted Runs: 29
Given N jobs, each denoted by a 2-tuples integer (pi, ri) where pi is the processing time and ri is the release time.
You must construct a schedule for these jobs on a single machine obeying:
(1) at most one job is processed at each point in time;
(2) no job is processed before its release time. Let Ci denote the time at which job i is finished processing, then the goal is to find the schedule that minimizes C1+C2+...+Cn.
INPUT
First line will be a positive integer N (1≤N≤100000) indicating the number of jobs.
Then N lines follow each containing a job (pi, ri), where 0≤pi≤10000 and 0≤ri≤10000.
OUTPUT
The minimum of C1+C2+...+Cn. Please mod the answer by 1e9+7.
Sample Input
3 1 0 3 1 1 2
Sample Output
9 Hint: Time 0: start Job 1. Time 1: finish Job 1 and start Job 2. Time 2: pause Job 2 and start Job 3. Time 3: finish Job 3 and start Job 2. Time 5: finish Job 2. C1+C2+C3=1+5+3=9.
Source: TJU School Competition 2015
这道题当时想到了最优队列实现但是自己比较搓,不太会实现,当时又卡了另一题所以就没过。
这题的主要思想在每个时间点选择可以开工的工作里所剩完成时间最短的。
#include<queue>
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#define N 100005
#define MOD 1000000007
struct Job{
int a,b;
}nodd[N];
int x,ans;
int cmp(Job a1,Job a2){
if(a1.b==a2.b) return a1.a<a2.a;
return a1.b<a2.b;
}
int main(){
int i,j,k;
int now,temp;
while(~scanf("%d",&x)){
ans=0;
for(i=0;i<x;i++)
scanf("%d %d",&nodd[i].a,&nodd[i].b);
sort(nodd,nodd+x,cmp);
i=0;
now=0;
priority_queue<int,vector<int>,greater<int> > q;
while(i<x){
now=nodd[i].b;
q.push(nodd[i].a);
for(j=i+1;j<x;j++){
if(nodd[j].b==now) q.push(nodd[j].a);
else break;
}
if(j==x) break;
else{
k=j;
while(now<nodd[k].b){
if(!q.empty()){
temp=q.top();
q.pop();
if(now+temp<=nodd[k].b){ //可以在下一个不同允许时间前的工作完成的
now+=temp;
ans=(ans+now)%MOD;
}else{ //完成其中一部分,没完成的继续入列
temp=temp-(nodd[k].b-now);
now=nodd[k].b;
q.push(temp);
}
}else break;
}
i=j;
}
}
while(!q.empty()){
temp=q.top();
q.pop();
now+=temp;
ans=(ans+now)%MOD;
}
printf("%d\n",ans);
}
}