2021年1月9日 时间都去哪了?囧
1.0-1背包问题
2.LIS问题:力扣300. 最长递增子序列
3.上午测了核酸。
4.傍晚跑步
总而言之,今天没有多少工作量。昨天有同学买了【Java主流技术栈SSM+SpringBoot商铺系统】,自己看了看,需要安装好些软件,还需要javaweb的基础。
明天计划:力扣题目刷到150。javaweb进行下去,或者学习计算机网络。
下面的笔记的图片没有上传成功,自己是先用Typora做的。明天试试解决。
解决办法:Typora笔记上传到CSDN解决图片问题—亲测有效!
转到2021.1.9-2021.1.31的learning record 首页
关注点:
剑指offer;leetcode。我刷了400道吧。包括剑指offer的题目70多道,剑指特别难的题可以放弃5-10个。大厂面试每轮都会有一到两到代码题,只要代码题都写出来,即使是别的问题回答的很烂,大概率也能过。剑指offer里的题出题频率还是蛮高的。重点还是代码就是LeetCode。中等,要很快的做出来,刷题要达到信手拈来的程度。刷题,刷题,刷题,很重要。数据结构,听听视频,先学一遍,再刷题,知道数据结构有什么类型。宽度优先遍历,广度优先遍历,二组查找,数组,链表,这些都挺重要的。可以跟着视频学可以的,先学一遍数据结构,知道题目的类型。
[算法与数据结构-综合提升C++版(快速应对面试)。这个明天可以看看。在下载了。]
正文:
9-5 0-1背包问题
0-1背包问题 视频题
贪心算法:优先放入平均价值最高的物品。通过实际的案例对比,发现是不可以的。贪心算法是无法解决这个问题的。不是全局最优解。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t76tmEoI-1610200560995)(第9章 动态规划基础.assets/image-20210109141239005.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LKTG3eQQ-1610200561001)(第9章 动态规划基础.assets/image-20210109141301474.png)]
0-1背包问题的状态转移方程。
F(n,c):将n个物品装进容量为c的背包,使得价值最大。
F(i,c)=max( F(i-1,c) , v(i) + F( i-1,c- w(i) ) )
F(i-1,c):第i个物品不放进背包中。
F( i-1,c- w(i) ) :第i个物品放进背包中,相应的,背包容量-物品i的重量w(i)。
(1)递归方法
public class p9_ex5_1 {
private int knapsack01(int[] w, int[] v, int c) {
int n = w.length;
//用[0,1,... ...,index]的物品来填充体积为c的背包的最大价值
// n-1 是说 物品 0到n-1
return bestValue(w, v, n - 1, c);
}
private int bestValue(int[] w, int[] v, int index, int c) {
// 边界条件 index是递减的,容量c也是递减的。
if (index < 0 || c < 0) {
return 0;
}
// 这里的 res 是说第 index 个物品 不放入背包中。
int res = bestValue(w, v, index - 1, c);
// 判断第 index 个物品的体积是否 小于等于背包的剩余容量。
// 否则直接返回上面得到的res。
if (c >= w[index]) {
//res2 是指放入index的物品,
int res2 = v[index] + bestValue(w, v, index - 1, c - w[index]);
res = Math.max(res, res2);
}
return res;
}
}
(2)记忆搜索
这里的记忆,是存储res。w,v,index,c中的index,c作为索引。w,v,是数组哦。
import java.util.Arrays;
public class p9_ex5_2 {
public static void main(String[] args) {
int[] w = new int[]{1, 2, 3};
int[] v = new int[]{6, 10, 12};
int c = 5;
System.out.println(knapsack01(w, v, c));
}
static int[][] memo;
private static int knapsack01(int[] w, int[] v, int c) {
int n = w.length;
// 这里的初始化 容量是 从0到c,是c+1个数。
memo = new int[n][c + 1];
for (int i = 0; i < n; i++) {
Arrays.fill(memo[i], -1);
}
// n-1 是说 物品 0到n-1
return bestValue(w, v, n - 1, c);
}
private static int bestValue(int[] w, int[] v, int index, int c) {
// 边界条件 index是递减的,容量c也是递减的。
if (index < 0 || c < 0) {
return 0;
}
if (memo[index][c] != -1) {
return memo[index][c];
}
// 这里的 res 是说第 index 个物品 不放入背包中。
int res = bestValue(w, v, index - 1, c);
// 判断第 index 个物品的体积是否 小于等于背包的剩余容量。
// 否则直接返回上面得到的res。
if (c >= w[index]) {
//res2 是指放入index的物品,
int res2 = v[index] + bestValue(w, v, index - 1, c - w[index]);
res = Math.max(res, res2);
}
memo[index][c] = res;
return res;
}
}
(3)动态规划
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ev0eEaDO-1610200561011)(第9章 动态规划基础.assets/image-20210109153720412.png)]
如果能理解上图,就理解了做题的思路了。
时间复杂度O(nC),空间复杂度O(nC)
import java.util.Arrays;
public class p9_ex5_3 {
public static void main(String[] args) {
int[] w = new int[]{1, 2, 3};
int[] v = new int[]{6, 10, 12};
int c = 5;
System.out.println(knapsack01(w, v, c));
}
private static int knapsack01(int[] w, int[] v, int c) {
int n = w.length;
if (n == 0) {
return 0;
}
// c+1是为了遍历0到c这些重量。
int[][] dp = new int[n][c + 1];
// dp 第0行的元素是多少。
// c+1 个元素 遍历列元素。
// 这里的j是指的容量c的遍历啊。遍历0到c这些重量。
// 因为下面的下面的双重for循环会使用i-1,所有先去计算得到i=0的数据。
for (int j = 0; j <= c; j++) {
// 如果剩余容量j≥第0个物品的重量,那就可以将第0个物品放入背包,此时背包的价值为v[0]
dp[0][j] = j >= w[0] ? v[0] : 0;
}
for (int i = 1; i < n; i++) {
for (int j = 0; j <= c; j++) {
// dp[i][j]是指考虑0到i这些物品,且容积为j的背包,所得到的最大值是多少。
// 1.不考虑第i件物品。
dp[i][j] = dp[i - 1][j];
// 剩余的容量j仍然可以将重量为w[i]的物品装进去。
if (j >= w[i]) {
dp[i][j] = Math.max(dp[i][j], v[i] + dp[i - 1][j - w[i]]);
}
}
}
// dp初始化大小为[n][c+1]
return dp[n - 1][c];
}
}
(4)背包问题的优化
F(i,c)=max( F(i-1,c) , v(i) + F( i-1,c- w(i) ) )
F(i-1,c):第i个物品不放进背包中。
F( i-1,c- w(i) ) :第i个物品放进背包中,相应的,背包容量-物品i的重量w(i)。
第i行元素,只是依赖于第i-1行元素,理论上只保留两行元素即可。
代码如下:
public class p9_ex5_3_2_1 {
public static void main(String[] args) {
int[] w = new int[]{1, 2, 3};
int[] v = new int[]{6, 10, 12};
int c = 5;
System.out.println(knapsack01(w, v, c));
}
private static int knapsack01(int[] w, int[] v, int c) {
int n = w.length;
if (n == 0) {
return 0;
}
int[][] dp = new int[2][c + 1];
for (int j = 0; j <= c; j++) {
dp[0][j] = j >= w[0] ? v[0] : 0;
}
for (int i = 1; i < n; i++) {
for (int j = 0; j <= c; j++) {
dp[i % 2][j] = dp[(i - 1) % 2][j];
if (j >= w[i]) {
dp[i % 2][j] = Math.max(dp[i % 2][j], v[i] + dp[(i - 1) % 2][j - w[i]]);
}
}
}
return dp[(n - 1) % 2][c];
}
}
[视频9-6 15min30s讲到了 0-1背包问题的变种]
(1)完全背包问题
完全背包问题:每个物品可以无限次的使用。这里由于背包的容量有限制,所以实际上每个物品的个数也会被限制,所以可以将完全背包问题转化为0-1背包问题。
(2)多重背包问题
多重背包问题:每个物品不止1个,而是有num[i]个。感觉就是上面问题的拓展延伸。
(3)多维费用的背包问题
多维费用的背包问题:考虑体积和重量两个维度
(4)等等变形的问题
[视频9.8-9]
最长上升子序列
300. 最长上升子序列
(1)LIS问题的o(n2)的解法
LIS(i)表示在【0…i】的范围内,选择数字num[i]作为结尾,可以获得的最长上升子序列的长度。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C1DmLSwo-1610200561021)(第9章 动态规划基础.assets/image-20210109212248191.png)]
max(j<i)指的是在所有的可能中选择最大值。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oSxGMqKs-1610200561024)(第9章 动态规划基础.assets/image-20210109213530842.png)]
import java.util.Arrays;
public class p9_ex6_300 {
public int lengthOfLIS(int[] nums) {
int n = nums.length;
if (n == 0) {
return 0;
}
// dp[i]表示以nums[i]为结尾的最长上升子序列的长度
int[] dp = new int[n];
// dp[i]初始值要赋值为1
Arrays.fill(dp, 1);
for (int i = 1; i < n; i++) {
// 这里的第二重for循环,是去考察num[i]之前所有的元素
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 取得dp数组中的最大值
int res = 1;
for (int i = 0; i < n; i++)
res = Math.max(res, dp[i]);
return res;
}
}
(2)LIS问题的o(log2n)的解法
去网络自学
376. 摆动序列【课后题】
(1)动态规划时间复杂度O(n2),状态转移方程
当nums[i] > nums[j] && i > j,up[i] = down[j] + 1
当nums[i] < nums[j] && i > j,down[i] = up[j] + 1
(2)简化版,时间复杂度O(n)
[视频9.8-9 26min 开始第二个视频]
最长公共子序列
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qM9WORSl-1610203753573)(第9章 动态规划基础.assets/image-20210109221138118.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HPDeNoGj-1610203753581)(第9章 动态规划基础.assets/image-20210109223300922.png)]
自行练习解决这个题目
(1)递归
(2)记忆化搜索
(3)动态规划
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oI6Jgqzl-1610203753586)(第9章 动态规划基础.assets/image-20210109221155714.png)]