有 个人排成一列(或一个环),第 个人手里有 张牌,在每一步操作中,可以让某人给他左边或右边的人一张牌,问最少多少步可以让每个人手中的牌数相等。
线性均分纸牌问题
定义 为总数的平均数,如果 不是整数的话,就是无解。否则要使每堆纸牌的数量一样多的话,那么经过移动后要使 。
对于第一堆牌,它会与第二堆牌产生 张牌的交换,多退少补,并累加答案。此时发现第一堆牌已经符合条件了,那么第一堆就可以忽略了,此时第二堆就变成了第一堆,继续重复上述步骤。
为什么这样做是最优的呢?可以发现在上述过程中,每一步都是必须的,没有多余的步骤,所以必然是最优解,这也是贪心思想的体现。
如果移牌的过程中出现负数怎么办?假设 在移动过程中是负数,那么接下来他一定会在 处拿牌。可以认为 向 给予牌是在 给予 牌之前,所以不影响结果。
对于如何统计答案,模拟上述过程,发现就是遍历每个人,并将其纸牌数变为 。假设要令 ,由算法流程可知,前 个人都有 ,而前 个人共有 张纸牌( 是 的前缀和),并且后面的人没有给前 个人牌,所以说现在的 ,故第 个人与第 个人之间的纸牌交换数量为 。而总的答案就是:
为了方便起见,可以一开始就将 ,那么最终就要使每个 ,那么答案就是:
环形均分纸牌问题
约定:此问题沿用上述线性问题解法中的定义
解法一
假设第 个人给了第 个人 张卡牌,特别的, 表示第 个人给了第 个人的牌的数量,所以此题的要求就是最小化 。
由题意可得以下方程组:
将 ()全部以 表示,可得:
令 ,那么 ,所以 。
所以只需要选确定 的值就行了,这是经典的仓库选址问题,由结论可得, 是 序列的中位数。
解法二
首先,有一个结论,那就是一定有一种最优解中有两个人之间没有发生纸牌交换。
证明
由解法一可得 是 序列的中位数,如果 的长度是奇数,那么 ,否则 ,所以 一定可以等于 中的某一个值,那么就有一个 ,得证。
有了上述结论,就可以断环为链,转化为线性问题,此时 ,所以只需要搞清楚 数组的变化即可。
假设在第 个人之后断开,此时的 数组就变为了 其对应的 数组也就变为了 因为每个 都减去了 ,所以 ,那么此时 ,与解法一的结论相似,即 为 序列的中位数。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效