題目連接:http://codeforces.com/gym/101775/problem/Bc++
Aori is very careless so she is always making troubles. One day she does it again, with N big troubles! But this time she seems to be at ease because she has found M Inklings to take all the blames. Each trouble can be measured by a severity number ai. Each trouble needs at least one Inkling to take the blame, and each Inkling can help Aori to take the blame for exactly one trouble. If two or more Inklings take the same trouble, they will take this blame together and discuss how to divide this trouble into.. some trivial things.. to reduce the pressure on each Inkling, as long as the total severity on Inklings is equal to the severity of this trouble.less
Inklings are so warm so that Aori wants to think a way to let the variance of severity on each Inkling to be minimal. Could you help Aori make her scapegoats?ide
Formally, the variance of variables is the expectation of the squared deviation of a variable from its mean:this
Input
The first line of the input gives the number of test cases, T. T test cases follow.spa
For each test case, the first line contains two integers N and M, where N is the number of troubles, and M is the number of Inklings. The next line contains N integers a1, a2, ..., aN representing the severity of the troubles that Aori makes.rest
1 ≤ T ≤ 100.
1 ≤ N ≤ M ≤ 2 × 10^5.
1 ≤ ai ≤ 10000..code
Output
For each test case, output one line containing "Case #x: y", where x is the test case number (starting from 1) and y is the minimal variance.orm
y will be considered correct if it is within an absolute or relative error of 10 - 8 of the correct answer.blog
Example
Input
3
3 6
1 2 3
5 10
5 6 7 8 9
6 6
1 1 4 5 1 4
Output
Case #1: 0.000000000000
Case #2: 0.400000000000
Case #3: 2.888888888889three
Note
For the first sample, Aori can let one Inkling to take the first trouble's blame, two Inklings for the second, and three Inklings for the third. The severity on each Inkling is 1 unit, so their variance should be 0.
題意:
如今某人闖禍了,產生了 $N$ 個鍋,每一個鍋有個嚴重點數,如今能夠安排 $M$ 個替罪羊去背鍋。
每一個替罪羊最多隻能背一個鍋。若一隻羊背一個鍋,則該鍋的嚴重點數所有算在它頭上;若多隻羊背同一個鍋,則每一個羊分到該鍋的一部分的嚴重點數。
如今考慮一種安排方案,使得全部的身上的嚴重點數的方差最小。
題解:
先考慮上 $N$ 只羊一一對應地背 $N$ 個鍋,剩下 $M-N$ 個替罪羊身上嚴重點數均爲 $0$,固然這樣並非最優解。
應當把再剩下 $M-N$ 個替罪羊安排進 $N$ 個鍋裏分攤責任,使得方差減少。考慮貪心的思路,每次安排進去一隻羊,都要使得方差減少最多。
考慮將新來的羊安排到某個任務,該任務嚴重點數爲 $a[i]$,且原來的背鍋羊數是 $num$,那麼首先每一個替罪羊分到的嚴重點數的平均數確定是不變的 $\overline{X} = \frac{a[1]+ a[2]+ \cdots + a[n]}{m}$,所以它本來對方差的貢獻爲 $\frac{1}{m} \cdot num \cdot (\frac{a[i]}{num}-\overline{X})^2$。
而如今新加進去一個替罪羊,這個任務對方差的新的貢獻爲 $\frac{1}{m} \cdot (num+1) \cdot (\frac{a[i]}{num+1}-\overline{X})^2$。
顯然,關鍵的差值就是 $\Delta = num \cdot (\frac{a[i]}{num}-\overline{X})^2 -(num+1) \cdot (\frac{a[i]}{num+1}-\overline{X})^2 = \frac{a[i]^2}{num \cdot (num+1)} - \overline{X}^2$,所以咱們讓每次挑一個任務讓它的 $\Delta + \overline{X}^2 = \frac{a[i]^2}{num \cdot (num+1)}$ 最大就行了,這個能夠用優先隊列。
AC代碼:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=2e5+10; const int eps=1e-10; int n,m; int a[maxn]; struct Node{ int id; int num; Node(int _id,int _num) { id=_id, num=_num; } inline double calc()const { return a[id]*a[id]*1.0/num/(num+1); } bool operator<(const Node& oth)const { return this->calc() < oth.calc()+eps; } }; priority_queue<Node> Q; int main() { int T; cin>>T; for(int kase=1;kase<=T;kase++) { scanf("%d%d",&n,&m); double aver=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); aver+=a[i]; Q.push(Node(i,1)); } aver/=m; for(int rest=m-n;rest>0;rest--) { Node now=Q.top(); Q.pop(); Q.push(Node(now.id,now.num+1)); } double ans=0; while(!Q.empty()) { Node now=Q.top(); Q.pop(); ans+=now.num*pow(a[now.id]*1.0/now.num-aver,2.0); } ans/=m; printf("Case #%d: %.9lf\n",kase,ans); } }