题目描述
有 n 个人在一个水龙头前排队接水,假如每个人接水的时间为 t[i],请编程找出这 n 个人排队的一种顺序,使得 n 个人的平均等待时间最小。
输入
第一行为一个整数 n。
第二行 n 个整数,第 i 个整数 t[i] 表示第 i 个人的等待时间 t[i]。
n<=1000,t[i]<=1e6
输出
输出文件有两行,第一行为一种平均时间最短的排队顺序;
第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。
样例输入
10 56 12 1 99 1000 234 33 55 99 812
样例输出
3 2 7 8 1 4 9 6 10 5 291.90
思路:
排队接水是贪心问题,要求求出等待接水的最小平均等待时间,以及最优解的排队顺序;
1:每一个人在接水时,在场剩余每个人都要经历一次他的打水时间。所以接水的时间为每个人接水的时间乘以这个人后面的人的人数的总和为接水的总时间,总时间除以接水的人数极为最短平均接水时间。所以排在前面的人接水的时间最短,则排在后面的人所需要等待的时间最短,所求出的既为解。
///5 5个人接水
///a[5]=1 2 3 4 5; 每个人接水的时间
a[1]=1 接水时间: t1=1*4
a[2]=2 接水时间:t2=2*3
a[3]=3 接水时间:t3=3*2
a[4]=4 接水时间:t4=4*1
a[5]=5 接水时间:t5=5*0
res=(t1+t2+t3+t4+t5)/5
///所以接水的时间总和为
for(int i=1;i<=n;i++)
t+=a[i]*(n-i);
///所以只要让排在前面接水的人所需要接水的时间最短,则总的接水时间最短,既为所求解
2:求最优解的排序可以使用结构体实现,但是需要用到结构体排序。
struct xx
{
double t; ///储存每个人的接水时间
int x; ///储存每个人的最初的排队顺序
}d[];
bool cmp(xx a,xx b)
{
return a.t<b.t; ///根据每个人排队接水的时间将结构体排序
}
sortsort(d+1,d+n+1,cmd);
代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1010;
struct xx
{
double t;
int x;
}d[N];
bool cmd(xx a,xx b)
{
return a.t<b.t;
}
int main()
{
int n;
cin >> n;
for(int i=1;i<=n;i++)
{
scanf("%lf",&d[i].t);
d[i].x=i;
}
sort(d+1,d+n+1,cmd);
for(int i=1;i<=n;i++) printf("%d ",d[i].x);
cout << endl;
double res=0;
for(int i=1;i<=n;i++)
{
res+=(n-i)*d[i].t;
}
printf("%.2lf\n",res/n);
return 0;
}