我正在解决codeforces中的问题。
我们的工作是找到使给定整数序列成为非递减序列的最低成本。我们可以在每一步增加/减少任何数量的序列1,它将花费1。
例如,当我们给出序列3,2,-1,2,1时,我们可以使序列不降低成本4(通过将3
减少到2
并增加-1
到2
,因此非递减序列将为2,2,2,2,11)
根据这个问题的editorial,我们可以使用2个序列的动态编程来解决这个问题,(一个是我们给出的序列,另一个是给定序列的排序序列)。
解决方案概要:
如果我们让a
成为原始序列,而b
是序列a
的排序序列,则让f(i,j)
成为获取所需的最小移动次数第一个i元素不减少的顺序,第i个元素最多为bj。然后我们可以如下复发。 (这是来自问题的社论)
f(1,1)=|a1-b1|
f(1,j)=min{|a1-bj|,f(1,j-1)}, j>1
f(i,1)=|ai-b1|+f(i-1,1), i>1
f(i,j)=min{f(i,j-1),f(i-1,j)+|ai-bj|}, i>1, j>1
我理解这种情况。但是,我无法弄清楚为什么我们应该将原始序列与其自身的排序序列进行比较,我不确定我们是否可以使用除给定序列之外的其他序列获得正确的最小成本。
我们如何证明此解决方案的正确性?我们怎样才能保证排序顺序的答案是最低成本?
答案 0 :(得分:1)
练习的重点是可以通过归纳证明这种复发。一旦证明,我们已经证明f(n,n)
是使用n
值最多为bn
的解决方案的最低成本。
要完成证明结果还有一步。这是为了证明n
值超过bn
的任何解决方案都可以在不增加最大值的情况下得到改进。但这是微不足道的 - 只是省略了第一个值中的一个+ 1超过bn
,并且你有一个更严格的解决方案而没有更大的最大值。因此,最大值大于bn
的最终解决方案最好不能达到最大值bn
。
因此我们有最佳解决方案。