USACO 重排干草&&BZOJ1045

USACO 重排干草&&BZOJ1045

Description

约翰订购了很多干草,他在农场里标记了 N 个位置。这些位置近似地构成一个圆环。他原打算 让送货司机在 i 号位卸下 Bi 捆干草。然而,送货司机搞乱了约翰的部署,胡乱卸货之后就离开了。 约翰数了数,目前在 i 号位有 Ai 捆干草,Ai 的总和是等于 Bi 的,说明司机至少没有少送货。

无奈之下,约翰只能自己来移动这些干草。约翰必须沿相邻位置来移动干草,每移动一捆干草到 一个相邻位置,要消耗约翰一单位的能量。请帮约翰规划一下,他最少消耗多少能量才能让所有位置 的干草数量从 {Ai} 变成 {Bi}?由于是圆环,所以 1 号位和 N 号位也算作是相邻的。

Input Format

• 第一行:单个整数 N ,1 ≤ N ≤ 10^5

• 第二行到 N + 1 行:第 i + 1 行有两个整数:Ai 和 Bi,1 ≤ Ai , Bi ≤ 1000

Output Format

单个整数:表示约翰消耗的最少能量之和

Sample Input

4
7 1
3 4
9 2
1 13

Sample Output

13

Hint

将 6 捆干草从 1 号位移到 4 号位,1 捆干草
从 3 号位移到 2 号位,6 捆干草从 3 号位移到 4号位

Solution

\(p[i]\)表示\(i\)运往\(i-1\)的干草数量,\(p[1]\)表示\(1\)运往\(n\)的干草数量。

则有\(A[i]+p[i+1]-p[i]=B[i]\),设$C[i]=A[i]-B[i],Sum[i]=\sum _{j=1}^i C[i] $

\(p[i]=p[i-1]-C[i-1]\)

\(p[2]=p[1]-C[1]=p[1]-Sum[1]\)

\(p[3]=p[2]-C[2]=p[1]-C[1]-C[2]=p[1]-Sum[2]\)

\(\begin{array}{cc} &&&&&& \vdots \end{array}\)

$p[1]=p[1]-C[1]-C[2]- \cdots -C[n]=p[1]-Sum[n]=p[1] $

\(Ans=\sum |p[i]|=\sum |p[1]-Sum[i]|\)

显然要让答案最小让\(p[1]\)等于\(Sum\)的中位数即可。

BZOJ1045是这题的简化版。

Code

#include <cstdio>
#include <algorithm>
#define LL long long

inline int read(){
    int num=0,k=1;char c=getchar();
    while (c<'0'||c>'9'){if (c=='-')k=-1;c=getchar();}
    while (c>='0'&&c<='9') num=(num<<1)+(num<<3)+c-48,c=getchar();
    return num*k;
}

LL n,ans,c[100007];

int main(){
    n=read();
    for (int i=1;i<=n;++i) c[i]=read()-read()+c[i-1];
    std::sort(c+1,c+n+1);
    for (int i=1;i<=n;++i)
     ans+=std::abs(c[i]-c[n>>1]);
    printf("%lld\n",ans);
}

转载于:https://www.cnblogs.com/hyheng/p/7788708.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值