BZOJ 1145--糖果传递(贪心)

1045: [HAOI2008] 糖果传递

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 4394  Solved: 2155
[Submit][Status][Discuss]

Description

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

Input

第一行一个正整数nn<=1‘000‘000,表示小朋友的个数.

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

Output

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

Sample Input

4
1
2
5
4

Sample Output

4

题目链接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=1145

Solution

    显然最后每个小朋友分到的糖数 s 是可以直接算的。。。

    假设刚开始每个第 i 个小朋友有 k [ i ] 个糖。。第 i 个小朋友给第 i - 1 个小朋友 t [ i ] 个糖,第 n 个小朋友给第一个小朋友 t [ n ] 个糖。。

    于是可以列出方程:  k [ i ] - t [ i ] + t [ i + 1 ] = s

    记 C [ i ] = ∑ ( k [ j ] - s ) (1 <= j <= i )

    于是:

       t [ 2 ] = s - k [ 1 ] + t [ 1 ] = t [ 1 ] - C [ 1 ]

      t [ 3 ] = s - k [ 2 ] + t [ 2 ] = 2*s - k [ 2 ] - k [ 1 ] + t [ 1 ] = t [ 1 ] - C [ 2 ]

       t [ 4 ] = t [ 1 ] - C [ 3 ]

      。。。

    我们要求的是 ∑ | t [ i ]  - C [ i - 1 ] | ,实质上就是给出数轴上若干个点 C0 ,C1 ,C2 。。。。 然后求一个点 x 使得总距离最小。。。

    显然用最中间的那个点是最优的。。。

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define N 1000050
#define LL long long
using namespace std;
inline int Read(){
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
int n;
int k[N],t[N];
LL mid,ans,s;
int main(){
    n=Read();
    for(int i=1;i<=n;i++){
        k[i]=Read();s+=k[i];
    }
    s=s/n;
    for(int i=1;i<=n;i++)
        t[i]=t[i-1]-k[i]+s;
    sort(t+1,t+n+1);
    mid=t[n/2];
    for(int i=1;i<=n;i++)
		ans+=abs(t[i]-mid);
    printf("%lld\n",ans);
    return 0;
}

  

  

This passage is made by Iscream-2001.

时间: 2024-10-19 03:22:14

BZOJ 1145--糖果传递(贪心)的相关文章

bzoj 1045: [HAOI2008] 糖果传递 贪心

1045: [HAOI2008] 糖果传递 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1812  Solved: 846[Submit][Status] Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 小朋友个数n 下面n行 ai Output 求使所有人获得均等糖果的最小代价. Sample Input 4 1 2 5 4 Sample Output 4

BZOJ 1045 糖果传递 题解 【递推乱搞就对了

1045: [HAOI2008] 糖果传递 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3505  Solved: 1626[Submit][Status][Discuss] Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 第一行一个正整数n<=987654321,表示小朋友的个数.接下来n行,每行一个整数ai,表示第i个小朋友得到的糖果的颗数. Outpu

P2512 [HAOI2008]糖果传递 - 贪心+中位数【环形均分纸牌问题】

P2512 [HAOI2008]糖果传递 Sol: 环形均分纸牌问题 考虑最基本的均分纸牌问题,相当于将环从1与n之间断开. 令\(res_i\)表示第\(i\)个人达到平均值所用步数,ave$表示糖果的平均数. 则 \(res_1=a_1-ave\) \(res_2=a_2-ave+res_1=a_1+a_2+2*ave\) \(res_3=a_3-ave+res_2=a_1+a_2+a_3-3*ave\) \(\dots\) \(res_i=a_i-ave+res_{i-1}=\sum_{j

bzoj 1045 [HAOI2008] 糖果传递 —— 贪心

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1045 好像是贪心...但这是一个环... 看博客:http://hzwer.com/2656.html 真是神奇的构造...还是应该大胆地先把各种变量都设出来再处理. 代码如下: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespa

[BZOJ1045] [HAOI2008] 糖果传递 (贪心)

Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 第一行一个正整数n<=1000000,表示小朋友的个数.接下来n行,每行一个整数ai,表示第i个小朋友得到的糖果的颗数. Output 求使所有人获得均等糖果的最小代价. Sample Input 4 1 2 5 4 Sample Output 4 HINT Source Solution 设$x[i]$表示$i+1$向$i$传的糖果数,$x[n]$表示$1$向

bzoj 1045 糖果传递

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1045 题解: 完全不求知怎么推导,于是引用hzw大犇的题解: 首先,最终每个小朋友的糖果数量可以计算出来,等于糖果总数除以n,用ave表示. 假设标号为i的小朋友开始有Ai颗糖果,Xi表示第i个小朋友给了第i-1个小朋友Xi颗糖果,如果Xi<0,说明第i-1个小朋友给了第i个小朋友Xi颗糖果,X1表示第一个小朋友给第n个小朋友的糖果数量. 所以最后的答案就是ans=|X1| + |X2|

糖果传递(基于贪心的数学问题)

0807 糖果传递 0x08「基本算法」练习 描述 有n个小朋友坐成一圈,每人有a[i]个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1.求使所有人获得均等糖果的最小代价. 输入格式 第一行一个正整数n<=1000000,表示小朋友的个数.接下来n行,每行一个整数a[i],表示第i个小朋友初始得到的糖果的颗数. 输出格式 一个整数,表示答案. 样例输入 4 1 2 5 4 样例输出 4 来源 NOI2008河南省选 解析: 首先,最终每个小朋友的糖果数量可以计算出来,等于糖果总数

bzoj1045: [HAOI2008] 糖果传递(数论)

1045: [HAOI2008] 糖果传递 题目:传送门(双倍经验3293) 题解: 一开始想着DP贪心一顿乱搞,结果就GG了 十分感谢hzwer大佬写的毒瘤数论题解: 首先,最终每个小朋友的糖果数量可以计算出来,等于糖果总数除以n,用ave表示. 假设标号为i的小朋友开始有Ai颗糖果,Xi表示第i个小朋友给了第i-1个小朋友Xi颗糖果,如果Xi<0,说明第i-1个小朋友给了第i个小朋友Xi颗糖果,X1表示第一个小朋友给第n个小朋友的糖果数量. 所以最后的答案就是ans=|X1| + |X2|

B1045 糖果传递 数学

糖果传递,一开始就想到了n^2的模拟贪心算法,但是一看,数据范围太大,好像只有O(N)能过...没啥方法,只好看题解,之后发现,woc,还有这种操作? 这个题直接可以用数学证明... 证明如下: 首先,最终每个小朋友的糖果数量可以计算出来,等于糖果总数除以n,用ave表示. 假设标号为i的小朋友开始有Ai颗糖果,Xi表示第i个小朋友给了第i-1个小朋友Xi颗糖果,如果Xi<0,说明第i-1个小朋友给了第i个小朋友Xi颗糖果,X1表示第一个小朋友给第n个小朋友的糖果数量. 所以最后的答案就是ans