分发瓜子(Ⅱ)——贪心+均值不等式

题目描述

解题思路

记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)。

证明如下:

  1. 贪心选择性质:我们每次少分发的瓜子数都尽可能地靠近均值,从数学的角度上来看,这样可以使总平方和最小,所以最优解一定包含贪心选择。

  1. 最优子结构性质:每次处理后,显然得到了一个和原问题性质相同但规模缩小的子问题,且原问题的最优解包含子问题的最优解。

关于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; 
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值