zoukankan      html  css  js  c++  java
  • BZOJ-1045 糖果传递 数学+递推

    1045: [HAOI2008] 糖果传递
    Time Limit: 10 Sec Memory Limit: 162 MB
    Submit: 2975 Solved: 1327
    [Submit][Status][Discuss]

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

    Input
    小朋友个数n 下面n行 ai

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

    Sample Input
    4
    1
    2
    5
    4

    Sample Output
    4

    HINT
    100% n<=987654321
    (这个数据范围加了特技,真实范围n<=1000000,Duang)

    数学题,可以说是**均分纸牌**的环状问题
    首先数组get【i】表示第i个小朋友从第i+1个小朋友那里得到的糖果,可正可负
    所以也可以表示第i+1个小朋友给第i个小朋友的糖果,即第i+1个小朋友失去的数量
    

    所以我们不难得出:
    candy【i】+get【i】-get【i-1】=pj(平均)
    这一步并不足以求解
    所以移项可得:
    get【i】=pj-candy【i】+get【i-1】
    上述式子可以推出get的值,那么问题在于从哪里开始最小
    问题为圆环,最小想到距离,距离想到中位!!
    于是…..A之

    代码精炼至极:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    
    #define maxn 1000002
    long long candy[maxn]={0};
    long long get[maxn]={0};
    
    int main()
    {
        int n;
        long long sum=0,pj=0;
        long long ans=0;
        scanf("%d",&n);
        for (long long i=1; i<=n; i++)
            {
                scanf("%d",&candy[i]);
                sum+=candy[i];
            }
        pj=sum/n;
        for (long long i=1; i<=n; i++)
            get[i]=get[i-1]+pj-candy[i];
        sort(get+1,get+n+1);
        long long mid=get[(1+n)/2];
        for (long long i=1; i<=n; i++)
            ans+=fabs(mid-get[i]);  
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    unity 反编译 step2 dll -->reflector
    unity 反编译 step1 disUnity
    rpg
    cmake使用
    linux mysqld的启动过程
    unity内存加载和释放
    Linux下MySql数据库常用操作
    MySQL主从复制与读写分离(非原创,谢绝膜拜)
    linux下IPTABLES配置详解
    linux下查看端口的占用情况
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5346249.html
Copyright © 2011-2022 走看看