码迷,mamicode.com
首页 > 其他好文 > 详细

[codechef July Challenge 2017] IPC Trainers

时间:2017-07-09 21:59:54      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:第三天   需要   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 }
View Code

 

[codechef July Challenge 2017] IPC Trainers

标签:第三天   需要   etc   getchar   最小值   algorithm   open   ++   描述   

原文地址:http://www.cnblogs.com/whc200305/p/7142684.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!