一、题目描述


二、题目详解
1. 问题背景
有一排数字在排队,每个数字都会出现两次。例如:1 2 1 3 2 3。
现在要求每一对相同的数字必须紧紧挨在一起。
操作规则如下:
- 可以拿走某一个数字放到队伍中的任意位置。
- 消耗体力 = 这个数字本身的大小。
例如:
- 移动
1→ 花 1 点体力 - 移动
100→ 花 100 点体力
2. 目标
不是问最少总共花多少体力,也不是问最少移动几次。
而是问:有没有一种办法,让每一次移动消耗的体力都 ≤ X,且这个 X 尽可能小。
换句话说,找一个最小的 X,只要禁止移动大于 X 的数字,剩下的数字还能不能自己乖乖地配对成功。
3. 核心思路:二分答案
我们假设规定体力超过 X 的数字不能动,剩下的能不能排好?这件事只有两种结果:能做到或做不到。
如果 X = 10 能做到,那 X = 11、12、13……一定也能做到。 答案是单调的,可以用二分查找。
4. 验证方法
假装选好了一个 X
- 所有数字 > X 的精灵不能动。
- 所以他们在队伍里的相对顺序一定不能变。
验证步骤
- 把所有 > X 的数字,按原顺序拿出来。
- 看它们是不是两个两个一样。
举例说明
原序列:1 2 1 3 2 3
假设 X = 1:
- 不能动的数字是:
2, 2, 3, 3 - 按原顺序取出:
2 3 2 3(注意:原序列中 1 被移除了,剩下的是 2, 1, 3, 2, 3 -> 过滤掉 <=1 的 1,剩下 2, 3, 2, 3) - 实际上原序列是
1 2 1 3 2 3,去掉 <=1 的数字(即 1),剩下2 3 2 3。 - ❌ 不是成对的(2 和 3 不同)→ 失败。
假设 X = 2:
- 不能动的数字是:
3, 3(大于 2 的) - 原序列
1 2 1 3 2 3,去掉 <=2 的数字(1, 2, 1, 2),剩下3 3。 - ✅ 正好一对 → 成功!
所以最小 X = 2。
5. 算法选择分析
本题不是贪心问题。局部最优选择(先动小的)不能保证全局最优,存在反例。可行性判定具有单调性,所以适合用二分 + 判定。


