1. 程式人生 > >[codechef July Challenge 2017] IPC Trainers

[codechef July Challenge 2017] IPC Trainers

限制 logs 想法 int char swap rain 會有 ont

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