题目传送门:https://www.luogu.com.cn/problem/P1223
题目:
Description:
有 nn 个人在一个水龙头前排队接水,假如每个人接水的时间为 Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小。
Input:
第一行为一个整数n;
第二行n个整数,第i个整数Ti;表示第i个人的等待时间Ti。
Output:
输出文件有两行,第一行为一种平均时间最短的排队顺序;第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。
题解:贪心。首先我们需要知道什么叫做“平均等待时间”?“平均等待时间”意思就是每个人等待的时间加起来然后除以人数n。知道这个之后题目就很简单了,我们只要想着把每个人等待的时间加起来尽量少就行了,那是不是就意味着只要让每个人的前缀和尽可能小不久行了,所以我们只要把数值小的元素放在前面不就实现了嘛,直接sort排序输出即可,用pair记录数值和下标即可。
点击查看代码
#include <bits/stdc++.h>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define all(x) (x).begin(), (x).end()
#define endl '\n'
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-9;
const int N = 2e5 + 10;
pii a[1010];
int main(void)
{
// Zeoy;
int t = 1;
// cin >> t;
while (t--)
{
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> a[i].first;
a[i].second = i;
}
sort(a + 1, a + n + 1);
double ans = 0.0, sum = 0.0;
for (int i = 1; i <= n; ++i)
{
cout << a[i].second << " ";
ans += sum;
sum += 1.0 * a[i].first;
}
cout << endl;
printf("%.2f\n", ans / n);
}
return 0;
}