我发现了一个贪婪的算法问题,在这里我们必须找到最小的不。使人坐在一起所需的跳跃。
这里是一篇文章的链接,供参考。
文章中的问题说明:
- Input: S = “. . . . x . . x x . . . x . .”
产出:5
说明:让第5位的人跳2位到第7位。让人在第13位跳跃3位到第10位seat.Therefore,总跳跃次数=2+3= 5。
- Input: S = “x x x . . . . . . . . x x x x x x”
产出: 24
说明:将乘员从第一、第二和第三位置分别移至第九、第十、第十一位置。因此,所需跳转总数=(11-3)+(10-2)+(9-3)= 24。
贪婪的解决方案是将元素转移到中间值。但还没有找到任何证据。是否存在使用这种方法的数学证明?
发布于 2022-06-15 20:02:01
设a[i]
是person i
(基于0的索引)的初始位置,其中人员的顺序设置为增加位置的顺序,而n
是人数的计数。假设最后的位置间隔,所有的人都连续地坐着,从t
位置开始。由于人的相对顺序没有变化,我们看到person i
从a[i]
移动到t + i
。何时以及如何发生这一移动对我们来说并不重要,但是从来不需要一个人跳到远离其目标位置的方向,因此它贡献了|a[i] - (t + i)| == |t - (a[i] - i)| == |t - b[i]|
跳转,其中由b[i] = a[i] - i
定义的b
是一个不递减的数组,因为a
严格地增加(因此b[i + 1] - b[i] == a[i + 1] - (a[i] + 1) >= 0
)。
因此,从位置t
开始的结果间隔的最小跳转总数是total[t] = sum(i, |t - b[i]|)
。现在,d_total[t] = total[t + 1] - total[t] == sum(i, |t - b[i] + 1| - |t - b[i]|) == sum(i, t >= b[i] ? 1 : -1) == count(i, t >= b[i]) - count(i, t < b[i]) == 2*count(i, t >= b[i]) - n
是total
的‘离散导数’,可以很容易地看到,随着t
的增加,d_total[t]
是不递减的,在由2*count(i, t == b[i])
对某些i
的t == b[i]
点处增加。total
的最小值发生在d_total[t]
为正的最小t
(意为count(i, t >= b[i]) > n/2
)。
特别地,对于奇数n == 2*k + 1
,这样的t
正好是b
的中值,结果区间的“中心”是t + k == b[k] + k == a[k]
,也就是a
的中值,正如在解中所假定的。即使是n == 2*k
,在b[k - 1]
和b[k]
之间也有包含t
的区间,其中total[t]
最小( t є [b[k - 1]; b[k] - 1]
和t == b[k]
的d_total[t] == 0
是最小的d_total[t] > 0
),这意味着得到的区间‘左中心’是t + k - 1 є [a[k - 1]; a[k] - 1]
(或者,等效地说,‘右中心’<代码>d40),所以在这种情况下,如果a[k] > a[k - 1]
,我们有几个最优的解决方案。
在任何情况下,正如我们所看到的,最优策略是跳向中间值(在偶数n
情况下是“中间间隔”),但是由于中位数被定义为这个区间结束的平均值,我们仍然可以说是“朝向中间值”的起始位置。
最后,这可能是显而易见的,但为了完整性:请注意,获得的全局最小t
不会产生超出输入字符串的间隔,因为在这两种奇偶校验情况下都很容易证明,a[0] <= t <= t + n - 1 <= a[n - 1]
和a
元素是使用该字符串的位置。因此,这个全局最小值总是适合我们的目的。
https://stackoverflow.com/questions/72629319
复制相似问题