题目
17964 水桶打水
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC;VC;JAVA
Description
有n个人(n<100000)带着大大小小的水桶容器(每人一个水桶)排队到r个(r<1000)水龙头打水,
他们装满水桶的时间分别是t1,t2,……,tn,并且时间是整数且各不相同,应如何安排他们的打水顺序
才能使他们花费的总时间和最少?
输入格式
分两行:第一行人数n和水龙头数r;第二行为t1 t2 …… tn。
输出格式
最少的所有人的总花费时间和。
输入样例
4 2
2 6 4 5
输出样例
23
提示
提示分析:
每个人整个打水的时间为:本人等待时间+本人实际充水的时间;
而本人的等待时间又为:排在本人之前所有人的充水时间之和。
本题目标是所有人打水花费的总时间和最小。那么,排在越前面的人,他的充水时间
计算次数就越多,因此充水时间越小的人排在前面可使所有人打水花费的总时间和越
小,所以用贪心法解答。
(1)将输入的充水时间按从小到大排序;
(2)将排序后的时间按顺序依次放入最早完成的水龙头的排队队列中;
(3)统计,输出合计后的完成时间和。
题解
每个人打水花费的总时间S=装水时间T+等待时间W
6 2
2 6 4 5 7 8
水龙头1 :
2->2+(2+5)->2+(2+5)+(2+(2+5)+7)
水龙头2 :
4->4+(4+6)->4+(4+6)+(4+(4+6)+8)
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 100000 + 10;
int n, r;
int t[N];
typedef long long LL;
int main()
{
cin >> n >> r;
priority_queue<int, vector<int>, greater<int>> heap;
for (int i = 0; i < r; i++)
heap.push(0);
for (int i = 0; i < n; i++)
cin >> t[i];
sort(t, t + n);
LL res = 0;
// 每个人打水花费的总时间S=装水时间T+等待时间W
// 6 2
// 2 6 4 5 7 8
// 水龙头1 :
// 2->2+(2+5)->2+(2+5)+(2+(2+5)+7)
// 水龙头2 :
// 4->4+(4+6)->4+(4+6)+(4+(4+6)+8)
for (int i = 0; i < n; i++)
{
int times = heap.top();
heap.pop();
times += t[i]; // 记录前缀和
res += times;
heap.push(times);
}
cout << res;
}