博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
付账问题(贪心)
阅读量:734 次
发布时间:2019-03-21

本文共 1031 字,大约阅读时间需要 3 分钟。

付账问题

几个人一起出去吃饭是常有的事。
但在结帐的时候,常常会出现一些争执。
现在有 n 个人出去吃饭,他们总共消费了 S 元。
其中第 i 个人带了 ai 元。
幸运的是,所有人带的钱的总数是足够付账的,但现在问题来了:每个人分别要出多少钱呢?
为了公平起见,我们希望在总付钱量恰好为 S 的前提下,最后每个人付的钱的标准差最小。
这里我们约定,每个人支付的钱数可以是任意非负实数,即可以不是 1 分钱的整数倍。
你需要输出最小的标准差是多少。
标准差的介绍:标准差是多个数与它们平均数差值的平方平均数,一般用于刻画这些数之间的“偏差有多大”。
形式化地说,设第 i 个人付的钱为 bi 元,那么标准差为 :
p1.png

输入格式

第一行包含两个整数 n、S;

第二行包含 n 个非负整数 a1, …, an。

输出格式

输出最小的标准差,四舍五入保留 4 位小数。

数据范围

1≤n≤5×105,

0≤ai,S≤109

输入样例1:

5 2333

666 666 666 666 666

输出样例1:

0.0000

输入样例2:

10 30

2 1 4 7 4 8 3 6 4 7

输出样例2:

0.7928

算法分析

我们都知道所取得的数与平均数越接近,标准差越小.这道题我们先将所有数排序,先算出每个人应该出多少钱,然后我们从前往后枚举每个人能付的钱,如果钱不够,那么多出来的钱需要后面的人去付.钱够的话就支付平均数就可以.所以我们只需要遍历每次支付的钱,还有剩下需要支付的钱就可以了.

代码实现

#include
#include
#include
#include
#include
using namespace std;const int maxn=5e5+5;int a[maxn];int n;double k;int main(){
cin>>n>>k; for(int i=1;i<=n;i++) cin>>a[i]; double avg=k/n,s=k;//s为剩下需要支付的钱 double res=0; sort(a+1,a+1+n); for(int i=1;i<=n;i++) {
double z=s/(n-i+1); if(a[i]

转载地址:http://rqagz.baihongyu.com/

你可能感兴趣的文章