洛谷P1031题解

洛谷P1031题解

有N堆纸牌,编号分别为1,2,…,N。每堆上有若干张,但纸牌总数必为N的倍数。可以在任一堆上取若干张纸牌,然后移动。

移牌规则为:在编号为1堆上取的纸牌,只能移到编号为2的堆上;在编号为NN的堆上取的纸牌,只能移到编号为N-1的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。

现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。

例如N=4,4堆纸牌数分别为:

①99②88③1717④66

移动3次可达到目的:

从 ③ 取4张牌放到 ④ (9,8,13,10)-> 从 ③ 取33张牌放到 ②(9,11,10,10)-> 从 ② 取11张牌放到①(10,10,10,10)。

这道题是一道很不错的贪心题,这个题目可以抽象成一类问题,即在每个人应该拥有的物品数都相等的情况下,满足只能相邻的人才能互相接济的条件,问最少需要接济多少次(当然主要理解这个意思,具体题目具体分析)。我们的贪心策略是,首先用每堆卡片数减去平均数,得到一组有正有负的数,我们的任务是把所有的数都变为零。因此,从左向右遍历,只要当前数不为0,就把它加给下一个数,不管正负,同时步数+1。为什么不管正负都加呢?其实正的加给下一个就相当于送给下一个,负的加给下一个就相当于从下一个里面拿

for(int i=1; i<=n; ++i) a[i] -= standard;
for(int i=1; i<=n; ++i)
{
    if(a[i] == 0) continue;
    else
    {
    	a[i+1] = a[i+1] + a[i];
    	ans++;
    }
}

确实是很有趣的贪心。这种减均值,然后考虑正负序列的做法还是挺常见的,值得积累一下。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值