贪心算法
在对问题求解时,总是做出在当前看来是最好的选择。
局部最优能推出全局最优
解题思路
1. 建立数学模型来描述问题
2. 把需要求解的问题分成若干个子问题
3. 对于每个子问题求解,得到子问题的局部最优解
4. 把子问题的局部最优解合成原来解问题的一个解
贪心的选择
最优子结构
动态规划
将一个问题拆成一个个子问题,直到子问题可以直接解决。然后把子问题答案保存起来,以减少重复计算。再根据子问题答案反推,得出原问题解的一种方法。
拆分子问题,记住过往,减少重复计算。
解决重叠子问题:备忘录
最长上升子序列
简称LIS
一个最长的、从小到大排序的子序列。最长上升子序列不一定是唯一的
最长公共子序列
简称LCS
背包
背包问题是一类经典的动态规划问题;
01背包
最基础的背包问题
给定一个容量为 V 的背包和 n 种不同的物品,每种物品有一个权值和一个体积。要求在不超过背包容量的前提下,选择一些物品,使得这些物品的总价值最大。
问题特点:每种物品仅有一件,可以选择放或不放
动态转移方程:dp[i][j] 表示前 i 件物品放入一个容量为 j 的背包中可以获得的最大价值
空间 | 价值 | 背包容量 | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|---|---|
2 | 4 | 0个物品 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 5 | 1个物品 | 0 | 0 | 4 | 4 | 4 | 4 |
1 | 2 | 2个物品 | 0 | 0 | 5 | 5 | 9 | 9 |
3 | 8 | 3个物品 | 0 | 2 | 5 | 7 | 9 | 11 |
4个物品 | 0 | 2 | 5 | 8 | 10 | 13 |
j<w[i] dp[i][j]=dp[i-1][j]
j>=w[i] dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])
优化
降低01背包的空间复杂度
j>=w[i] dp[j]=max(dp[j],dp[j-w[i]]+v[i])
完全背包
完全背包是与 01 背包类似,但不同之处在于每个物品可以重复选择,即可以选择多次。
给定一个容量为 V 的背包和 n 种不同的物品,每种物品有一个权值和一个体积。要求在不超过背包容量的前提下,选择一些物品,使得这些物品的总价值最大。
多重背包
多重背包是与完全背包类似,但不同之处在于每个物品有选择次数。
给定一个容量为 V 的背包和 n 种不同的物品,每种物品有一个权值和一个体积。要求在不超过背包容量的前提下,选择一些物品,使得这些物品的总价值最大。