标签:第三天 需要 etc getchar 最小值 algorithm open ++ 描述
IPCTRAIN: 训练营教练
题目描述
本次印度编程训练营(Indian Programming Camp,IPC)共请到了 N 名教练。训练营的日
程安排有 M 天,每天最多上一节课。第 i 名教练在第 Di 天到达,直到训练营结束才离开。第 i 名
教练希望上 Ti 节课。要是少上了课,那么教练会感到扎心,每少上一节,扎心值就会加 Si。
作为主办方,你希望最小化所有教练的扎心值之和。
输入格式
输入的第一行包含一个整数 T,代表测试数据的组数。接下来是 T 组数据。
每组数据的第一行包含两个整数 N 和 D。接下来 N 行,每行包含三个整数 Di
, Ti
, Si。
输出格式
对于每组数据,输出一行,包含一个整数,代表扎心值之和的最小值。
数据范围和子任务
? 1 ≤ T ≤ 10
? 1 ≤ N, D, Si ≤ 105
? 1 ≤ Di
, Ti ≤ D
子任务 1(40 分):
? 1 leqN, D, Si ≤ 103
子任务 2(60 分):
? 无附加限制
样例数据
输入
3
2 3
1 2 300
2 2 100
2 3
1 1 100
2 2 300
2 3
3 2 150
1 1 200
输出
100
0
150
样例解释
对于第一组数据,两名教练都想上两节课,分别在第 1 和第 2 天到达。可以安排第一名教练
上头两天的课程,第二名教练上最后一天的课程。这样第二名教练少上了一节课,扎心程度为
100。可以证明不存在更好的排课方案。
对于第二组数据,可以让所有教练都满意。
对于第三组数据,第一名教练第三天才到,却想上两节课。一天一节课,训练营就三天,所
以只能让他扎心。第二名教练第一天就到了,但只想上一节课,所以可以给他安排第 1 天或者第 2
天。但无论如何,总有一天没有课上。
这题还是比较水的。当然是一个贪心的想法。在某一天,很多人会要求上课。那怎么办?挑代价最大的呗,之后一直都挑代价最大的(且需要能取,没有取完),最后就能得到最优解。那么想到了这里,我们自然会有一个用堆维护的想法。每一天从堆里面挑出最大的一个,那么这个教授需要要求上课的天数少了一天。如果某个教授要求天数变为了0,那么他就没事了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 int n,D,len,heap[100005]; 7 long long ans; 8 struct per{ 9 int arr,cla,unh; 10 bool operator < (const per &other) const {return arr<other.arr;} 11 }a[100005]; 12 inline int read(){ 13 int x=0; char ch=getchar(); 14 while (ch<‘0‘||ch>‘9‘) ch=getchar(); 15 while (ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); 16 return x; 17 } 18 void put(int x){ 19 heap[++len]=x; 20 for (int son=len; son>1; son>>=1) 21 if (a[heap[son]].unh>a[heap[son>>1]].unh&&a[heap[son]].unh>a[heap[son>>1]].unh) swap(heap[son],heap[son>>1]); 22 else break; 23 } 24 void get(){ 25 heap[1]=heap[len],heap[len]=0,len--; 26 for (int fa=1; (fa<<1)<=n;){ 27 int son; 28 if (a[heap[fa<<1]].unh>a[heap[fa<<1|1]].unh||(fa<<1|1)>n) son=fa<<1; else son=fa<<1|1; 29 if (a[heap[son]].unh>a[heap[fa]].unh) swap(heap[son],heap[fa]),fa=son; 30 else return; 31 } 32 } 33 int main(){ 34 for (int Ts=read(); Ts; Ts--){ 35 n=read(),D=read(),ans=len=0; 36 memset(a,0,sizeof a); 37 memset(heap,0,sizeof heap); 38 for (int i=1; i<=n; i++) a[i].arr=read(),a[i].cla=read(),a[i].unh=read(); 39 sort(a+1,a+1+n); 40 int j=1; 41 for (int days=1; days<=D; days++){ 42 while (j<=n&&a[j].arr==days) put(j),j++; 43 if (!len) continue; 44 int x=heap[1]; a[x].cla--; 45 if (!a[x].cla) get(); 46 } 47 for (int i=1; i<=n; i++) ans+=(long long)a[i].unh*a[i].cla; 48 printf("%lld\n",ans); 49 } 50 return 0; 51 }
[codechef July Challenge 2017] IPC Trainers
标签:第三天 需要 etc getchar 最小值 algorithm open ++ 描述
原文地址:http://www.cnblogs.com/whc200305/p/7142684.html