石子合并(copy的 我不会)

石子归并[1]

——浅谈贪心思想在动态规划中的应用

题目大意:

在一个操场上摆放着一排nn≤1000)堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的花费。

试编程求出将n堆石子合并成一堆的最小花费。

算法分析:

这是一道经典的动态规划问题,用m[i,j]表示第i堆石子合并到第j堆石子所需的最小花费,w[i,j]表示第i堆石子到第j堆石子的石子总数。状态转移方程如下:

上述算法的状态总数为O(n2),每个状态转移的状态数为O(n),每次状态转移的时间为O(1),所以总的时间复杂度为O(n3)。

显然,这个简单易懂的算法的过于低效了,我们需要进行优化。

 

我们尝试寻找动态规划中的冗余。不难发现,在枚举决策k的时候,上述算法实在是太盲目了,因为当有一些k如果作为决策点,肯定得不到最优解,我们可以不去枚举他们。

这是一种贪心的思想!

 

s[i,j]表示使得m[i,j]取到最小时的k。可以用四边形不等式[2]证明出

s[i,j]≤s[i,j+1]≤s[i+1,j+1],     ij

这说明m[i,j]的决策单调。于是状态转移方程可以变成如下的形式:

整体的时间复杂度则变为了:

   

本题的相关证明详见参考文献[3]

本题小结:

决策单调的动态规划是一类很常见的问题,例如NOI2004的hut就是一道不错的根据决策单调的性质来优化动态规划的题目。根据决策单调的性质,我们避免了一些无用的决策枚举,从而使得算法的复杂度降了级,这是贪心思想的经典体现。



[1] 经典问题

[2] 当函数w[i,j]满足 时,称w满足四边形不等式。

posted on 2011-10-25 22:20  ushiojamie  阅读(425)  评论(0)    收藏  举报