洛谷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++;
}
}
确实是很有趣的贪心。这种减均值,然后考虑正负序列的做法还是挺常见的,值得积累一下。