AcWing_1235 付账问题(贪心)

AcWing

1235. 付账问题

贪心。首先要知道标准差表示的是数据的波动程度,其值越大波动越大。要使得标准差小,我们就要尽可能使得数据都比较接近平均值。

那么这题贪心策略应该是这样的:首先算出平均值$s/n$,把数据从小到大排序,如果某个人的钱低于该值,那么他一定是将钱全部支付,然后其余不够的其他人平摊。

但是,由于之前那个人钱不够,那么就会导致剩下人支付的平均值会增大,所以在这个平摊过程中很有可能存在某个人钱又低于这个平均值,又需要剩下的人平摊。如此反复,直到支付完成。

#include <bits/stdc++.h>
using namespace std;
typedef long double LD;
int n;
LD s;
const int N = 5e5 + 10;
int a[N];
int main(){
    scanf("%d %Lf", &n, &s);
    for(int i = 0; i <= n - 1; i ++) cin >> a[i];
    sort(a, a + n);
    LD aver = s / n, ss = s, sum = 0;
    for(int i = 0; i <= n - 1; i ++){
        LD aav = ss / (n - i);
        if(a[i] < aav)  aav = a[i];
        ss -= aav;
        sum += (aav - aver) * (aav - aver);
    }
    printf("%.4Lf", sqrt(sum / n));
    return 0;
}