问题描述
有n个人排队到r个水龙头去打水,他们装满水桶的时间t1、t2………..tn为整数且各不相等,应如何安排他们的打水顺序才能使他们总共花费的时间最少?
输入格式
第一行n,r (n<=500,r<=75)
第二行为n个人打水所用的时间Ti (Ti<=100);
输出格式
最少的花费时间
样例输入
3 2
1 2 3
样例输出
7
数据规模和约定
其中80%的数据保证n<=10
题记:
这道题的意思是要计算排队打水的人,每个人的等待时间和打水时间,总和。
比如样例给的:3个人,2个水龙头。
第一个人在第一个水龙头,排队0分钟,打水1分钟,共1分钟。
第二个人在第二个水龙头,排队0分钟,打水2分钟,共2分钟。
第三个人在第一个水龙头,排队1分钟,打水3分钟,共4分钟。
结果共1+2+4=7分钟。
我的计算方法:
先举个例子
10个人,3个水龙头,10个人打水时间分别是1、2、3、4、5、6、7、8、9、10的例子。
每个人打水时间是1+2+3+……+10;
重点是等待时间:
第一个水龙头排队的人:1、4、7、10号。等待时间:1*3 + 4*2 + 7*1。
第二个水龙头排队的人:2、5、8号。等待时间:2*2 + 5*1。
第三个水龙头排队的人:3、6、9号。等待时间:3*2 + 6*1。
时间总和就是都加起来,最后结果是94。
思路:
先按打水时间由少到多排序,再把排好队的人在水龙头前一条龙排队。(打水时间短的先打水,等待时间会短一些)
计算打水时间+等待时间。等待时间计算思想看上面的例子,你懂得。
C++程序如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main(void){
int n, r, cnt, ct, t, sum=0;
cin >> n >> r;
int *a = new int[n];
for(int i = 0; i < n; i++)
{
cin >> a[i];
sum += a[i];
}
sort(a, a+n);
cnt = n/r;
ct = n%r;
t= r;
for(int j=0; j<r; j++)
{
int tmp = cnt;
if(ct){
for(int i=0; i<cnt+1; i++)
sum += a[i*r+j]*(tmp--);
ct--;
}
else{
tmp = cnt-1;
for(int i=0; i<cnt; i++)
sum += a[i*r+j]*(tmp--);
}
}
cout << sum << endl;
delete [] a;
return 0;
}