代码随想录打卡Day35

news/2024/12/22 17:15:11/

今天还是以看视频为主,主要是力扣上合适的题目不多,今天主要是学习0-1背包的二维数组解法和一维数组解法,今天题目不多,但是debug花了我好久时间。。。主要还是对0-1背包不够熟悉。

46. 携带研究材料(卡码网)

这道题我先用二维dp数组来做的,dp[i][j]的含义就是:对于容量为j的背包,通过合理选择物品[0,i]的组合,所能达到的最大价值即为dp[i][j]。
二维数组的初始化需要明确几点:1.dp数组大小 2.初始化哪些地方
第1点,对于m种物品,最大容量为n的背包,我们需要定义一个m行n+1列的二维向量;
第2点,初始化下标为0的行和列,对于j = 0,背包容量为0,自然装不下任何东西,所装物品的价值也为0,对于第一个(下标为0)物品(不一定是负重最小),当背包容量依次为1,2,…,n时,背包的价值只有两种取值,要么是0(背包装不下),要么是value[0](背包装得下,value[0]是物品0的价值)。
接下来就是确定递推公式,对于dp[i][j],
当背包选择不装物品i或是空背包都无法装下物品i时,dp[i][j] = dp[i - 1][j];
当背包选择装下物品i时,dp[i][j] = dp[i - 1][j - weight[i]] + value[i];
装下了物品i不一定能带来更高的价值,有可能物品i的负重很大,但是价值却很小,所以我们需要在两种情况下取最大值。
在二维dp数组中,先遍历背包容量还是先遍历物品都是可以的。

#include<iostream>
#include<vector>
#include <algorithm>using namespace std;int main(){//数据读取int M, N;vector<int> value;vector<int> weight;cin >> M;cin >> N;int input;for(int i = 0; i < M; i++){cin >> input;weight.push_back(input);}for(int i = 0; i < M; i++){cin >> input;value.push_back(input);}//开始动态规划vector<vector<int>> dp(M, vector<int>(N + 1)); //初始化为全0数组//dp数组初始化for(int i = 0; i < M; i++)dp[i][0] = 0;for(int i = 1; i <= N; i++){if(i < weight[0])  //背包装不下第一个物品dp[0][i] = 0;elsedp[0][i] = value[0];}int MAX = *max_element(dp[0].begin(), dp[0].end());//开始遍历递推dp数组for(int i = 1; i < M; i++){for(int j = 1; j <= N; j++){if(j < weight[i])dp[i][j] = dp[i - 1][j];else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);MAX = max(dp[i][j], MAX);}}cout << MAX << endl;return 0;
}

如果将二维数组降维成一维数组,则dp[j]的含义为背包容量为j时的最大价值,则初始化就非常简单了,假设背包最大容量为N定义一个大小为N+1的一维全零向量即可。在递推过程中,dp[j] = max(dp[j], dp[j - weight[i]] + value[i]),当然,j < weight[i]的情况下,无需对dp[j]进行改动。在遍历顺序上,必须先遍历物品再遍历背包,因为一维数组会反复利用,在每一层外循环结束后,dp数组中保存的值都是考虑加入物品i后的最优选择下的最大价值,在遍历背包时必须倒序遍历,确保同一种物品只被添加一次。

416. 分割等和子集

这道题目我把部分思路都想出来了,想到了判断数组求和除以二,想到了用一维dp数组来做,但是还是没有想明白,最后只能看视频,这道题目的巧妙之处在于使背包的最大容量为sum / 2,物品就是数组里面的数字,数组里的数字既代表了物品的负重,也代表了物品的价值,所以本题遍历时的原则就是在背包装得下的情况下,负重越大越好。在循环过程中,一旦发现在背包负重为sum / 2时,价值也达到了sum / 2,就说明数组能够分割成两个总和相等的子数组。当然,在对输入数组求和后,需要先判断sum的奇偶性,如果为奇数的话直接返回false即可(无论如何也分不出来),为偶数的话再进行动态规划五部曲。

class Solution {
public:bool canPartition(vector<int>& nums) {//1.确定dp[j]的含义:[0, j]的数字中最优组合的最大价值//2.确定递推公式  dp[j] = max(dp[j], dp[j - weight[i]] + value[i])//3.dp数组初始化 dp初始化为0向量//4.确定遍历顺序:先物品(数字),再背包(从后往前)//5.打印数组(省略)int sum = accumulate(nums.begin(), nums.end(), 0);//若总和为奇数则无法平分if(sum % 2 != 0) return false;//以下代码为总和为偶数情况vector<int> dp(sum / 2 + 1, 0);  for(int i = 0; i < nums.size(); i++){for(int j = dp.size() - 1; j >= 1; j--){if(j < nums[i]) break;  //装不下dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);if(dp[j] == sum / 2) return true;}}return false;}
};

今天题目虽然不多,但是做的我汗流浃背。。。。


http://www.ppmy.cn/news/1527110.html

相关文章

大数据新视界 --大数据大厂之数据挖掘入门:用 R 语言开启数据宝藏的探索之旅

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

vue3中把封装svg图标为全局组件

在vue3中我们使用svg图标是下面这样子的 <svg style"width:30px;height:30px;"><use xlink:href"#icon-phone" fill"red"></use></svg>第次使用图标都要写这么多重复的代码&#xff0c;很不方便&#xff0c;所以&#x…

JavaSE基础——第三章 运算符

本专题主要为观看韩顺平老师《零基础30天学会Java》课程笔记&#xff0c;同时也会阅读其他书籍、学习其他视频课程进行学习笔记总结。如有雷同&#xff0c;不是巧合&#xff01; 运算符是一种特殊的符号&#xff0c;用于表示数据的运算、赋值、比较等&#xff0c;包括&#xff…

常用 Git 命令

可视化学习网站&#xff1a;Learn Git Branching 一、初始化仓库 git init&#xff1a;在当前目录下初始化一个新的 Git 仓库。 二、添加和提交更改 git add <file>&#xff1a;将指定文件添加到暂存区。可以使用通配符&#xff0c;如 git add *.py 添加所有 .py 文件…

TSRPC+Cocos

TSRPC文档: https://tsrpc.cn/docs/get-started/api.html 创建 先创建一个默认的会话项目&#xff0c;找一个文件夹在控制台运行以下代码&#xff1a; npx create-tsrpc-applatest first-api --presets browser # 或者 yarn create tsrpc-app first-api --presets browser运…

linux-L6 linux管理服务的启动、重启、停止、重载、查看状态命令

来重启一下某一个服务 1.使用命令查看所有的服务状态 Systemctl找到其中的相关的服务 systemctl status xxx_你的应用程序的服务__xxx3.重启该服务 systemctl restart xxx_你的应用程序的服务__xxx下面的是备用&#xff0c;需要用的时候&#xff0c;查看就好了 启动服务 …

java程序员入行科目一之CRUD轻松入门教程(一)

之前在操作MySQL的时候&#xff0c;都是采用Navicat&#xff0c;或者cmd黑窗口。 无论使用什么方式和MySQL交互&#xff0c;大致步骤是这样的 建立连接&#xff0c;需要输入用户名和密码编写SQL语句&#xff0c;和数据库进行交互 这个连接方式不会变&#xff0c;但是现在需要 基…

JVM程序计数器

JVM的程序计数器是线程私有的内存区域&#xff0c;它记录着当前线程执行的字节码指令地址&#xff0c;是Java虚拟机中至关重要的组件&#xff0c;确保多线程环境下程序的正确执行与流畅切换。其重要性不容忽视&#xff0c;是Java程序高效、稳定运行的基石。 一、程序计数器介绍…