AcWing 1235. 付账问题

原题链接

考察:贪心

思路:

       很明显付的钱尽量是花费钱的平均值.如果有人的钱<平均值mid,付的钱是他自己的钱,那么mid-a[i]就要钱>mid的同学补上.但是这里模拟补上比较复杂.当a[i]<mid时,付了a[i]的钱,要付的钱变成了s-a[i],在剩下n-i个人中,要让他们付s-a[i]的钱,且保持标准差值最低.即累加(bi-s/n)2的值最小.当bi-s/n的累加和取到定值,就有均值不等式,当bi-s/n相等时取最小值.因为前面的人钱数<mid,所以不能取mid,只有剩下n-i个人全都取到s-a[i]的均值才能尽量最小.

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cmath>
 5 using namespace std;
 6 const int N = 500010;
 7 int a[N],cnt;
 8 double ans,b[N],sum;
 9 int main()
10 {
11     int n,s;
12     scanf("%d%d",&n,&s);
13     double mid = (double)s/n;
14     double tmp = mid;
15     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
16     sort(a+1,a+n+1);
17     for(int i=1;i<=n;i++)
18     {
19         if(a[i]<mid)
20         {
21             s-=a[i];
22             ans+=(a[i]-tmp)*(a[i]-tmp);
23             mid = s*1.0/(n-i);
24         }else ans+=(mid-tmp)*(mid-tmp);
25     }
26     ans/=n;
27     printf("%.4lf\n",sqrt(ans));
28     return 0;
29 }

 

posted @ 2021-02-26 19:12  acmloser  阅读(66)  评论(0编辑  收藏  举报