アルゴリズムのトレーニング地下水問題
制限時間:メモリ制限が1.0S:64.0メガバイト
問題の説明
学校は、水室を有する水室は、学生のために利用可能な水が開いたm個のタップの合計が装備され、毎秒蛇口あたりの水の量に等しく、それは1です。ありnは学生が水を取る準備ができて、彼らの最初の注文を受けた水が決定されています。これらの学生が順次1からnまでの番号を押しを受けた水は、その後、学生の数は、iがWI水です。水がかかり始めると、1メートルは学生に各1つのタップ数であり、そして同時に、水道水をオンにします。その地下水の要件を完了した一部の学生jはWJすると、学生はすぐに位置j kの学生が水を取るようになっ引き継ぐ水受けに並んで待っています。この置換プロセスは、水の無駄なく、瞬間的です。Jは、学生X秒を受信水の最後に完了し、最初の学生K X + 1は、第次いで水を直ちに開始しました。水の現在の数を受信する場合、N番目の水道水、他のM-N「オフ番目のタップ「未満mより、のみnは」。N名今与えられた学生のアクセス水は、その後、水は、上記の規則に従って、すべての学生はどのくらいの水、その後、完成秒を尋ねました。
入力形式
ライン1二つの整数n及びmは、それぞれ、スペースで区切られ、その後、水道水の数の数。行2 nは整数W1、W2、...、Wnが、二つの整数間の各スペースで区切られた、WIは私に水学生の数を表します。
出力フォーマット
出力のみ一行、水にアクセスするために必要な総時間を示す整数。
サンプル入力
5
3 4 4 1 2 1
サンプル出力
4
サンプル入力
8
4 23 71 87 32 70 93 80 76
サンプル出力
163
サンプル説明1 O
第一、第二、3次に水。第一、第二の端部で、次いで、水の量は、1,2,3番3当たりの学生が完成学生が、次いで水、3号4号学生の学生が水との接触を交換し始めるでいます。2秒3、次いで水。学生はその後、水は2,4 1番であるように、2つの秒の終了時に、次いで、水は、学生あたり1,2ありました。3秒、3人は水を取ります。3秒の終わりには、その後、水は3号への生徒のアクセスなど、学生一人当たり1,2及び4号2.4学生は、その後、完成した水、第4号5号学生の学生は、水との接触を交換し始めました。第二に4、3、その後水。4秒の終わりには、次に水は、すべて完了した後、水、すなわち、その後終え水4,5数1.1,2,5水の学生への学生のアクセス、など学生一人当たり1,2でした。総水量は4秒の時間を受けます。
スケールデータと規則
1≤N≤1,1≤m≤100とm≤N。
1≤のWi≤100
#include <cstdio>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
int n, m;
int w[10005] = { 0 };
int total_seconds = 0, finished_seconds;
scanf("%d %d", &n, &m);
for (int i = 0; i < n; ++i)
scanf("%d", &w[i]);
vector<int> taps;
for (int i = 0; i < m; ++i)
taps.push_back(w[i]);
int next_student = m;
make_heap(taps.begin(), taps.end(), greater_equal<int>{});
finished_seconds = taps.front();
total_seconds += finished_seconds;
pop_heap(taps.begin(), taps.end());
taps.pop_back();
while (taps.size() > 0 || next_student < n)
{
for (int i = 0; i < taps.size(); ++i)
taps[i] -= finished_seconds;
if (next_student < n)
taps.push_back(w[next_student++]);
make_heap(taps.begin(), taps.end(), greater_equal<int>{});
finished_seconds = taps.front();
total_seconds += finished_seconds;
pop_heap(taps.begin(), taps.end());
taps.pop_back();
}
printf("%d", total_seconds);
return 0;
}