题目
题解一 记忆化搜索
F(n,C)考虑将n个物品放进容量为C的背包使得价值最大
F(i,c)=F(i-1,c) //不需要将第i个物品放进背包
=v(i)+F(i-1,c-w(i)) //需要将第i个物品放进背包
F(i,c)=max(F(i-1,c)),v(i)+F(i-1,c-w(i))
/// 背包问题
/// 记忆化搜索
/// 时间复杂度: O(n * C) 其中n为物品个数; C为背包容积
/// 空间复杂度: O(n * C)
public class Solution1 {
private int[][] memo;
//w重量,v价值,c背包容积
public int knapsack01(int[] w, int[] v, int C){
if(w == null || v == null || w.length != v.length)
throw new IllegalArgumentException("Invalid w or v");
if(C < 0)
throw new IllegalArgumentException
("C must be greater or equal to zero.");
int n = w.length;
if(n == 0 || C == 0)
return 0;
memo = new int[n][C + 1];
return bestValue(w, v, n - 1, C);
}
// 用 [0...index]的物品,填充容积为c的背包的最大价值
private int bestValue(int[] w, int[] v, int index, int c){
if(c <= 0 || index < 0)
return 0;
//重叠子问题用记忆化搜索
if(memo[index][c] != -1)
return memo[index][c];
//不放第index个物品
int res = bestValue(w