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 }