食物 | 质量/weight (100g) | 价值/value(10g) |
---|---|---|
米饭 | 2 | 4 |
黄瓜 | 1 | 5 |
西红柿 | 1 | 8 |
牛肉 | 3 | 10 |
动动吃货的小脑筋,就知道,养分价值最大化的选择是 牛肉+黄瓜+西红柿 共 23(10g)养分! 但是该怎么使用程序计算出答案呢? html
肚子的资源有限,对每一种食物有两种选择:吃或者不吃。 判断的依据有两点:数组
(1)肚子可否装得下食物?bash
(2)吃他的价值,是否比不吃他的价值大?大则吃下,不大则不吃。spa
假设d(i,w)表示肚子剩w(g)时,有 i 样食物可供选择,咱们能获得的最大价值。i 表示第 i 样食物。咱们须要求的是d(4,5).net
根据上面的逻辑(1)设计
若是肚子装不下,由于食物i没装进去,那么d(i,w) = d(i-1,w)code
肚子装得下,那我须要判断 [不放] d(i-1,w) 和 [放] d(i-1,w-w[i])+v[i] 谁大。cdn
结合上面两条规律,咱们获得:htm
d(i, w)=max{ d(i-1, w), d(i-1,w-w[i]) + v[i] }blog
咱们给每样食物加上序号
假如咱们考虑吃或不吃从下向上按照序号顺序 4,3,2,1
d(4,5)表示只有牛肉、西红柿、黄瓜、米饭能够选择时,能获得的最大价值。若是我知道d(3,5)和d(3,2),我就能获得d(4,5)
d(4 , 5)=max{ d(3,5) , d(3,5-3) }=max{ d(3,5) , d(3,2) + 10}
d(4,5)表示只有西红柿、黄瓜、米饭能够选择时,能获得的最大价值。若是我知道d(2,5)和d(2,4),我就能获得d(3,5)
d(3 , 5)=max{d(2,5) , d(2,4)}
按照上面的往下分解,最终都会指向d(0,w)~逻辑以下图:
d(0,w)表明选 0 件物品的放入背包容量为 w 的背包的最大价值,因此为 0。d(i,0)表明选 i 件物品放入背包容量为 0 的背包的最大价值,也为 0。
将树图的d值继续整理获得最优价值表
var value = [5, 8, 4, 10],
size = [1, 1, 2, 3],
d = [],
n = 4,
C = 5;
//初始化数组
for (var k = 0; k <= n; ++k) {
d[k] = [];
}
for (var i = 0; i <= n; ++i) {
for (var w = 0; w <= C; ++w) {
d[i][w] = (i == 0) ? 0 : d[i - 1][w];
if (i > 0 && w >= size[i - 1])
d[i][w] = Math.max(d[i - 1][w], d[i - 1][w - size[i - 1]] + value[i - 1]);
}
}
console.log(d[4][5])//23
复制代码
01背包问题的这种解法让我感觉到了递归的强大,将大问题转换成小问题,而后获得小问题的答案向上求解!
连接:www.nowcoder.com/questionTer… 来源:牛客网 一种双核CPU的两个核可以同时的处理任务,如今有n个已知数据量的任务须要交给CPU处理,假设已知CPU的每一个核1秒能够处理1kb,每一个核同时只能处理一项任务。n个任务能够按照任意顺序放入CPU进行处理,如今须要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间。
动态规划之01背包问题--表格思路来源