zoukankan      html  css  js  c++  java
  • 【BZOJ1045】[HAOI2008] 糖果传递 贪心

    【BZOJ1045】[HAOI2008] 糖果传递

    Description

      有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。

    Input

      第一行一个正整数n<=987654321,表示小朋友的个数.接下来n行,每行一个整数ai,表示第i个小朋友得到的
    糖果的颗数.

    Output

      求使所有人获得均等糖果的最小代价。

    Sample Input

    4
    1
    2
    5
    4

    Sample Output

    4

    题解:面对环上的问题我们仍然考虑把环拆开

    我们先不考虑n—1的传递,只考虑1—2—3。。—n的传递,此时有无脑贪心:

    第i人向第i-1个人传递s[i-1]-(i-1)*ave个糖果,代价是s[i-1]-(i-1)*ave的绝对值,其中s是前缀和,ave是平均数

    当1能向n传递时,假设传递的个数是x,则以后的所有i向i-1传递的数量都会减去x,但由于要取绝对值,所以如果s[i-1]-(i-1)*ave-x为正,则总代价会-x,若为负,则总代价会+x,那么最优情况肯定是是s[i-1]-(i-1)*ave-x中正数和负数的个数相等,即x取s[i-1]-(i-1)*ave的中位数(别忘了把0加上)

    注意开long long

     

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    long long a[1000010],b[1000010];
    long long n,ans,tot;
    int main()
    {
    	scanf("%lld",&n);
    	int i;
    	for(i=1;i<=n;i++)	scanf("%lld",&a[i]),tot+=a[i];
    	tot/=n;
    	for(i=2;i<=n;i++)	b[i]=b[i-1]+a[i]-tot;
    	sort(b+1,b+n+1);
    	for(i=1;i<=n;i++)	ans+=abs(b[i]-b[n+1>>1]);
    	printf("%lld",ans);
    	return 0;
    }

     

  • 相关阅读:
    Trie
    [转]Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)
    [Bzoj2242]常见数值算法
    JavaScript百炼成仙(记录笔记)
    tcpreplay重放报文,tcpdump能抓到包,应用程序收不到包
    用jquery tools来实现选项卡
    ExtNet第二篇
    线性表最简单的表示
    c语言中线性表基本操作方法
    ExtNet第一篇
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6550123.html
Copyright © 2011-2022 走看看