【前端】自学基础算法 -- 25.动态规划-01背包问题
动态规划-01背包问题
简介
动态规划(Dynamic Programming,简称 DP)是一种解决复杂问题的方法,它将问题分解为更小、更简单的子问题,并存储这些子问题的解,以避免重复计算。动态规划通常用于优化问题,如求最大值、最小值或计数问题。
动态规划的基本思想是将大问题分解为小问题,并从小问题开始解决,逐步构建到原问题的解。具体步骤如下:
- 定义状态:明确问题的解是什么,并定义状态变量。
- 建立状态转移方程:根据问题的性质,建立状态之间的递推关系。
- 初始化状态:确定初始状态或边界条件。
- 计算顺序:确定计算顺序,通常是从边界条件开始,逐步计算到最终状态。
- 返回结果:根据计算结果返回最终答案。
01背包问题:
给定 n 个物品和一个容量为 W 的背包,每个物品都有自己的重 w 和价值 v。
问: 如何选择物品放入背包,使得背包内物品的总价值最大,同时不超过背包的容量。
实现方法
/**
* 01背包问题
* 给定 n 个物品和一个容量为 W 的背包,每个物品都有自己的重 w 和价值 v。
* 问如何选择物品放入背包,使得背包内物品的总价值最大,同时不超过背包的容量。
* @param {*} weights
* @param {*} values
* @param {*} capacity
* @returns
*/
// 定义函数 knapSack,参数包括物品重量数组 weights,物品价值数组 values,以及背包容量 capacity
function knapSack(weights, values, capacity) {
// 获取物品数量
var n = values.length
// 初始化一个二维数组 T,用于存储子问题的解
var T = []
// 遍历每个物品
for (let i = 0; i < n; i++) {
// 为当前物品初始化一个行
T[i] = []
// 遍历每个可能的背包容量
for (let j = 0; j <= capacity; j++) {
// 如果背包容量为0,则最大价值为0
if (j === 0) {
T[i][j] = 0
continue
}
// 如果当前物品重量大于背包容量,则不能选择当前物品
if (j < weights[i]) {
// 如果是第一个物品,则最大价值为0
if (i === 0) {
T[i][j] = 0
} else {
// 否则,最大价值为不选择当前物品时的最大价值
T[i][j] = T[i - 1][j]
}
continue
}
// 如果是第一个物品且背包容量可以容纳该物品,则最大价值为该物品的价值
if (i === 0) {
T[i][j] = values[i]
} else {
// 否则,最大价值为选择当前物品或不选择当前物品时的最大价值
T[i][j] = Math.max(values[i] + T[i - 1][j - weights[i]], T[i - 1][j])
}
}
}
// 返回最后一个物品在背包容量为 capacity 时的最大价值
return T[n - 1][capacity]
}
// 定义物品重量和价值数组,以及背包容量
var weights = [2, 3, 4]
var values = [3, 4, 5]
var capacity = 5
// 调用 knapSack 函数并打印结果
console.log(knapSack(weights, values, capacity)) // 输出: 7