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;
}