一、动态规划
动态规划算法的关键在于解决冗余,这是动态规划算法的根本目的。把问题分解成若干个子问题,然后记录下每个子问题的解,避免重复计算,再从众多子问题中选出最优解。
点击这查看上一篇动态规划详解
问题描述:给定 n 个重量为w1,w2···wn,价值为v1,v2···vn,背包的承重量为 W 。
背包问题是给定 W 重量的背包装入尽可能高价值的物品。F(i,w):前 i 个物品,当前背包还可以装w重量。
我们可以把前 i 个物品中放入重量为 W 的背包中价值最大化问题分解成两个问题:
- 装入背包的物品不包括第 i 个物品,F(i , w) = F(i -1 , w);
- 装入背包的物品包括第 i 个物品,F(i , w) = F(i -1 , w - wi) + vi;
现在假设有四个物品,重量分别为 2, 1, 3, 2; 价值为 12, 10, 20, 15; 给定一个承重为 W = 5 的背包,求装入物品的最大价值是多少?
首先,根据以上步骤,可以将问题分解为:
- F(4, 5) = max{F(3, 5), F(3, 3) + 15 };
- F(3, 5) = max{F(2, 5), F(2, 2) + 20 };
- F(3, 3) = max{F(2, 3), F(2, 0) + 20 };
- F(2, 5) = max{F(1, 5), F(1, 4) + 10 };
.
.
. - F(0, 5) = 0;
- F(i, 0) = 0;
同样的,我们需要定义一个二维数组来保存每一个子问题的解,避免重复计算。
代码如下:
public class Main{
static int[