排队接水

D14557. 排队接水

时间限制:1.0s 内存限制:256.0MB
输入文件名:test.in 输出文件名:test.out
问题描述
  有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti(<=100),请编程找出这n(<=10000)个人排队的一种顺序,使得n个人的平均等待时间最小。?>>
输入格式
  共两行,第一行为n;第二行分别表示第1个人到第n个人每人的接水时间T1,T2,…,Tn,每个数据之间有1个空格。
输出格式
  平均等待时间(输出结果精确到小数点后两位)。
样例输入
10
56 12 1 99 1000 234 33 55 99 812
样例输出
291.90

思路:
贪心策略:按照时间排序,每次选取接水时间最少的人,第i个人的等待时间是前i个人的接水时间总和,注:不包括自己的接水时间。
由此使用前缀和求出等待时间,算出总和,/n出解。
贪心证明:
两个人接水时间分别是t1,t2,t1 < t2。1号先接水,2号的等待时间为t1,平均时间为t1/2。反之为t2/2,时间更多。由此时间少的人先接水,可以使解更有,贪心策略正确。
算法复杂度:
O(2*N)。N <= 10000,稳得一批。
Code:

#include<bits/stdc++.h>

using namespace std;

int n,tsum;
int sum[10010],wa[10010];
double ans;

int main(){
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> wa[i];
	sort(wa + 1, wa + n + 1);
	for (int i = 1; i <= n; i++)
		sum[i] = sum[i - 1] + wa[i - 1];
	for (int i = 1; i <= n; i++)
		tsum += sum[i];
	ans =(double) tsum / n;
	printf("%.2lf\n",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/sun915/p/9496496.html