题目描述
解题思路
记S为总期望值,则少得到瓜子的总数为sum=S-m,为一定值,设 每个竹鼠少得到瓜子数为xi,则Σxi=sum,要使Σxi^2最小,由均值不等式可知,每个xi应该尽量靠近均值sum/n。考虑到Ei可能小于sum/n,这时xi为了尽量向均值靠近从而使平方和最小,应取Ei。故贪心策略如下:
设目前有n只竹鼠尚未分发瓜子,未分发的瓜子总共还有sum个,对于我们要处理的竹鼠i,少分发瓜子数xi=min(sum/n,Ei)。
证明如下:
贪心选择性质:我们每次少分发的瓜子数都尽可能地靠近均值,从数学的角度上来看,这样可以使总平方和最小,所以最优解一定包含贪心选择。
最优子结构性质:每次处理后,显然得到了一个和原问题性质相同但规模缩小的子问题,且原问题的最优解包含子问题的最优解。
关于sum/n非整数时是向上还是向下取整,说明如下:
显然之后每一个xi都会取sum/n,那么每一个xi的取值相差不过1,若向下取整,后面的数字会比先前的数字大1,若向上取整,先前的数字会比后面的数字大1,总平方和是一样的。
代码实现
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main ( )
{
// freopen("input.txt","r",stdin);
ll m,n,sum=0,ans=0;
cin>>m>>n;
vector<ll> E(n);
for(ll i=0;i<n;++i){
cin>>E[i];
sum+=E[i];
}
sum-=m;
sort(E.begin(),E.begin()+n);
for(ll i=0;i<n;++i){
ll x=min(E[i],sum/(n-i));
sum-=x;
ans+=x*x;
}
cout<<ans<<endl;
return 0;
}