Knapsack Problem
背包问题
背包问题(Knapsack problem)是一种组合优化的 NP 完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择才能使得物品的总价格最高。
1. 背包问题
这个问题是指每个物体的可以拆分,即可以得到单位重量的价值,最终要求选择后的结果使得物品的总价格最高,这种问题最后背包一定会放满,使用贪心算法。具体实现过程如下:
1 | weights = [3, 4, 8, 5] |
2. 01背包问题
01背包问题是指每个物体都有且只有一个(即选或不选),最终要求选择后的结果使得物品的总价格最高,这种问题最后背包不一定会放满,使用动态规划算法。具体实现过程如下:
f[n][C] 表示容量 C 是否可以放置前 i 个物品。
f[i][j] = max( f[i-1][j-weights[i]] + values[i] if j>=weights[i], f[i-1][j])
1 | weights = [3, 4, 8, 5] |
3. 非01背包问题
非01背包问题是指每个物体都有很多个(无限个),最终要求选择后的结果使得物品的总价格最高。具体实现过程如下:
1 | weights = [3, 4, 8, 5] |
4. 变种之选硬币问题
给定一些物品数组和一个目标值,问有多少种可以组成目标的组合数,比如给定物品数组 [2,3,6,7] 和目标值 7 (2种可能)。可以考虑使用动态规划:
dp[n][C] 表示从前i中里面组成 C 的组合数,则
dp[n][C] = dp[n-1][C] + dp[n-1][C-values[n-1]* 1] + dp[n-1][C-values[n-1]* 2] + …
1 | values = [2, 3, 6, 7] |