动态规划解决0-1背包问题

时间:2022-11-10 18:41:09

之前上算法课的时候老师一味的强调这个很难,也很重要,我们也在认真学,但是这个老师太水了,还是中南大学的博士,讲个问题都讲不清楚,可能他自己心里是理解并明白的,但是就是讲述不清楚,我们班上的人也非常反感这个老师。考试也是靠各种手段混过去了。现在看到这个问题,就记录一下,免得以后忘记了。

基本的思想就不用赘述了,跟分治法很类似,在0-1背包问题中,可能最难理解的地方就是那个递推公式了吧,我也是想了很久都没有想通,后来自己在纸上照着公式带了几个例子进去,慢慢的搞明白了。

问题原文:

01背包(ZeroOnePack): 有N件物品和一个容量为V的背包。(每种物品均只有一件)第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。

用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:

f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}

就是这个公式,我带了几个例子进去才想通是怎么回事。
我们在考虑第i件物品要不要放进去的时候,有两种情况,放或者不放,如何决定呢,那就是两种情况都算出结果然后进行比较。这也就是那个公式的来历,第一种情况不放进去,很简单,就是f[i][v];第二种情况,放进去,要放进去总得先有空间,所以先把总的v减去第i件物品的体积,然后 f[i-1][v-c[i]] 在之前的矩阵里面是可以直接获取到的,然后加上i件物品的价值,跟第一种情况比较,那么就出结果了。 这里关键在于之前算过的各种情况都用一个二维数组把价值存起来了,所以能够很方便的获取。