2010年NOIP全國聯賽普及組html
學校裏有一個水房,水房裏一共裝有m 個龍頭可供同窗們打開水,每一個龍頭每秒鐘的供水量相等,均爲1。ios
如今有n 名同窗準備接水,他們的初始接水順序已經肯定。將這些同窗按接水順序從1到n 編號,i 號同窗的接水量爲wi。接水開始時,1 到m 號同窗各佔一個水龍頭,並同時打開水龍頭接水。當其中某名同窗j 完成其接水量要求wj 後,下一名排隊等候接水的同窗k立刻接替j 同窗的位置開始接水。這個換人的過程是瞬間完成的,且沒有任何水的浪費。即j 同窗第x 秒結束時完成接水,則k 同窗第x+1 秒馬上開始接水。若當前接水人數n’不足m,則只有n’個龍頭供水,其它m−n’個龍頭關閉。測試
如今給出n 名同窗的接水量,按照上述接水規則,問全部同窗都接完水須要多少秒。spa
第1 行2 個整數n 和m,用一個空格隔開,分別表示接水人數和龍頭個數。
第2 行n 個整數w一、w二、……、wn,每兩個整數之間用一個空格隔開,wi 表示i 號同
學的接水量。code
輸出只有一行,1 個整數,表示接水所需的總時間。htm
5 3
4 4 1 2 1blog
4隊列
n<=10000, m<=100ip
第1 秒,3 人接水。第1 秒結束時,一、二、3 號同窗每人的已接水量爲1,3 號同窗接完水,4 號同窗接替3 號同窗開始接水。
第2 秒,3 人接水。第2 秒結束時,一、2 號同窗每人的已接水量爲2,4 號同窗的已接水量爲1。
第3 秒,3 人接水。第3 秒結束時,一、2 號同窗每人的已接水量爲3,4 號同窗的已接水量爲2。4 號同窗接完水,5 號同窗接替4 號同窗開始接水。
第4 秒,3 人接水。第4 秒結束時,一、2 號同窗每人的已接水量爲4,5 號同窗的已接水量爲1。一、二、5 號同窗接完水,即全部人完成接水。
總接水時間爲4 秒。ci
問題分析
直接模擬正常的排隊打水的過程:前m我的依次上前各自使用一個水龍頭。
從第m+1我的開始,每一個人都要考慮應該使用哪個水龍頭,具體決策的依據是:每次都選擇目前最先結束工做的那個水龍頭。
因此,w[ ]前m個元素不動,直接用來記錄m個水龍頭目前還須要工做的時長。
1 #include <stdio.h> 2 int findMin(int *a,int begin,int end);//返回a[begin]~a[end]之間的最小值的下標 3 int findMax(int *a,int begin,int end);//返回a[begin]~a[end]之間的最大值的下標 4 int main(int argc, char *argv[]) 5 { 6 int n,m,w[10005]={0},i,t; 7 scanf("%d%d",&n,&m); 8 for(i=0;i<n;i++) 9 scanf("%d",&w[i]); 10 for(i=m;i<n;i++) 11 { 12 t=findMin(w,0,m-1); 13 w[t]=w[t]+w[i]; 14 } 15 16 t=findMax(w,0,m-1); 17 printf("%d\n",w[t]); 18 return 0; 19 } 20 int findMin(int *a,int begin,int end)//返回a[begin]~a[end]之間的最小值的下標 21 { 22 int i,minI=begin; 23 for(i=begin+1;i<=end;i++) 24 { 25 if(a[i]<a[minI]) minI=i; 26 } 27 return minI; 28 } 29 int findMax(int *a,int begin,int end)//返回a[begin]~a[end]之間的最大值的下標 30 { 31 int i,maxI=begin; 32 for(i=begin+1;i<=end;i++) 33 { 34 if(a[i]>a[maxI]) maxI=i; 35 } 36 return maxI; 37 }
這裏沒有考慮一種特殊的狀況:水龍頭的數量比人數多的狀況,題目的測試數據也沒有這種狀況。如果存在這個狀況,那麼答案就是直接找出w[ ]的最大值便可。
另外一種思路 參照https://www.cnblogs.com/xianyue/p/7040537.html
這道題也可使用優先隊列(或者說「最小堆」)去作。優先隊列在C++的queue庫中有一個priority_queue的實現。
咱們首先將m個數放入優先隊列,而後每次從其中取出一個最小的數,再將這個數加上接下來要進去的那我的k對應的數(即爲k離開的時間)。最後咱們將優先隊列裏面的全部數取出來,其中最大的那個數就是答案。
關於有線隊列能夠閱讀這裏:https://www.cnblogs.com/Deribs4/p/5657746.html
1 #include <iostream> 2 #include <queue> 3 #include <vector> 4 using namespace std; 5 priority_queue<int, vector<int>, greater<int> > que; 6 int n, m, a[10010], res = 0; 7 int main() 8 { 9 cin >> n >> m; 10 for (int i = 0; i < n; i ++) 11 cin >> a[i]; 12 for (int i = 0; i < m; i ++) 13 que.push(a[i]); 14 for (int i = m; i < n; i ++) 15 { 16 int t = que.top(); 17 que.pop(); 18 que.push(a[i] + t); 19 } 20 while (!que.empty()) 21 { 22 int t = que.top(); 23 que.pop(); 24 if (t > res) 25 res = t; 26 } 27 cout << res << endl; 28 return 0; 29 }