您的位置:首页 > 其它

背包问题求第K优解

2013-09-28 09:28 197 查看
【基本思想】

    将每个状态都表示成有序队列,将状态转移方程中的max/min转化成有序队列的合并。这里以01背包为例讲解一下。

【分析】

    首先看01背包求最优解的状态转移方程:F[i][v]=max(F[i-1][v],F[i-1][v-C[i]]+W[i])。如果要求第K优解,一个首先想到的肯定是修改状态数组,改为F[i][v][k]。其中F[i][v][k]表示前i个物品中,背包大小为v时,第k优解的值。既然k表示第k优解,那么显然F[i][v][k](1<=k<=K),这K个数的值是由大到小排列的,所以它可以看作是一个有序队列。

    再看原状态转移方程,可以理解为:F[i][v]这个有序队列是由F[i-1][v]和F[i-1][v-C[i]]+W[i]这两个有序队列合并得到的。那么可以把F[i-1][v]改为F[i-1][v][1...K],把F[i-1][v-C[i]]+W[i]则理解为F[i-1][v-C[i]][1...K]的每个数加上W[i],那么这又是两个有序队列。合并这两个有序队列并结果的前K项存储到F[i][v][1...K]中的复杂度是O(K).

    最后的第K优解的答案是F
[V][K]。总的时间复杂度就是O(VNK).

【原理】

    简单说一下原理。实际上,一个正确的状态转移方程的求解过程遍历了所有可用的策略,也就覆盖了问题的所有方案。只不过由于是求最优解,所以其他在任何一个策略上达不到最优的方案都被忽略了(没有输出)。如果把每个状态表示成一个大小为K的数组,并在这个数组中有序地保存该状态可取到的前K个最优值。那么,对于任两个状态的max运算等价于两个由大到小的有序队列的合并。

【提示】

    注意看题面,如果题目对于“第K优解”的定义是:将策略不同但权值相同的两个方案看作是一个解(通常是这样)。那么维护有序队列时要保证队列里的数没有重复。

注:选自崔添翼大牛的《背包问题九讲》,文章有些许改动。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: