第四十四天| 卡尔网 52. 携带研究材料、518. 零钱兑换 II、377. 组合总和 Ⅳ

01背包问题卡尔网 52. 携带研究材料

题目链接:52 携带研究材料

题干:小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。他需要带一些研究材料,但是他的行李箱空间有限。这些研究材料包括实验设备、文献资料和实验样本等等,它们各自占据不同的重量,并且具有不同的价值。

小明的行李箱所能承担的总重量为 N,问小明应该如何抉择,才能携带最大价值的研究材料,每种研究材料可以选择无数次,并且可以重复选择。

  • 输入描述:

第一行包含两个整数,N,V,分别表示研究材料的种类和行李空间 

接下来包含 N 行,每行两个整数 wi 和 vi,代表第 i 种研究材料的重量和价值

  • 输出描述:

输出一个整数,表示最大价值。

思考:此题为完全背包问题。01背包和完全背包唯一不同就是体现在遍历顺序上,所以直接针对遍历顺序分析。

01背包内嵌的循环是从大到小遍历,为了保证每个物品仅被添加一次。而完全背包的物品是可以添加多次的,所以要从小到大去遍历,保证物品可重复取,具体原因在01背包问题中讲过。

但此处物品和背包容量遍历顺序可以调换。因为dp[j] 是根据 下标j之前所对应的dp[j]计算出来的。 只要保证下标j之前的dp[j]都是经过计算的就可以。

若先遍历物品再遍历背包则代码如下:

// 先遍历物品,再遍历背包
for(int i = 0; i < weight.size(); i++) { // 遍历物品for(int j = weight[i]; j <= bagWeight ; j++) { // 遍历背包容量dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}
}

若先遍历背包再遍历物品则代码如下:

// 先遍历背包,再遍历物品
for(int j = 0; j <= bagWeight; j++) { // 遍历背包容量for(int i = 0; i < weight.size(); i++) { // 遍历物品if (j - weight[i] >= 0) dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}cout << endl;
}

代码:

#include<iostream>
#include<vector>
using namespace std;//采用滚动数组存储的最大价值
int knapsack_1D(vector<int>& weight, vector<int>& value, int bagWeight) {//dp[j]表示背包空间为j的情况下,从所有物品里任取,能达到的最大价值vector<int> dp(bagWeight + 1, 0);for (int i = 0; i < weight.size(); i++)     //遍历物品for (int j = weight[i]; j <= bagWeight; j++)     //遍历背包重量dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);return dp[bagWeight];  
}int main() {int bagWeight, objectNum;cin >> objectNum >> bagWeight;vector<int> weight(objectNum, 0);vector<int> value(objectNum, 0);for (int i = 0; i < objectNum; i++) {cin >> weight[i];cin >> value[i];}cout << knapsack_1D(weight, value, bagWeight) << endl;system("pause");
}

Leetcode 518. 零钱兑换 II

题目链接:518 零钱兑换 II

题干:给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。

请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。

假设每一种面额的硬币有无限个。 

题目数据保证结果符合 32 位带符号整数。

思考:动态规划。由于不同面额的硬币可取多次,因此本题为完全背包的类似问题。

  • 确定dp数组以及下标的含义

dp[j]:硬币总额为i的组合个数

  • 确定递推公式

dp[j] 就是所有的dp[j - coins[i]](考虑coins[i]的情况)相加。所以递推公式:dp[j] += dp[j - coins[i]];

  • dp数组如何初始化

从递推公式可以看出,如果dp[0] = 0 的话,后面所有推导出来的值都是0。

下标非0的dp[j]初始化为0,这样累计加dp[j - coins[i]]的时候才不会影响真正的dp[j]

  • 确定遍历顺序

本题背包(硬币总额)以及物品(硬币)的先后遍历顺序与纯完全背包不同,后者求得装满背包的最大价值是多少,和凑成总和的元素有没有顺序没关系,即:有顺序也行,没有顺序也行!

但本题要求凑成总和的组合数,元素之间明确要求没有顺序。因此要分别尝试先遍历物品(硬币)以及先遍历背包(硬币总额)两种情况。


尝试先遍历背包(硬币总额)后遍历物品(硬币)会发现求出的是排列个数不是组合个数。举例

硬币面值只要1和2,要求硬币总金额为3的组合个数。不难得到dp[1] = 1; dp[2] = 2;

在处理dp[3]时出现问题,按递推公式dp [3] = dp [2]  + dp[1],结果为3,而实际只有2种组合。

多出来的一种从哪来的呢?

从dp[2]:总金额为2组合分别为 {1,1}以及{2},dp[1]:总金额为1组合为{1}

按递推公式则将组合{1,2}和{2,1}都算一种组合,而这两组合一样。

而先遍历物品(硬币)后遍历背包(硬币总额)可行。

  • 举例推导dp数组

输入: amount = 5, coins = [1, 2, 5] ,dp状态图如下:

代码:

class Solution {
public:int change(int amount, vector<int>& coins) {vector<int> dp(amount + 1, 0);      //dp[i]表示硬币总额为i的组合个数dp[0] = 1;for (int i = 0; i < coins.size(); i++)          //遍历硬币for (int j = coins[i]; j <= amount; j++)    //遍历硬币总额dp[j] += dp[j - coins[i]];return dp[amount];}
};

Leetcode 377. 组合总和 Ⅳ

题目链接:377 组合总和 Ⅳ

题干:给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target。请你从 nums 中找出并返回总和为 target 的元素组合的个数。

题目数据保证答案符合 32 位整数范围。

请注意,顺序不同的序列被视作不同的组合

思考:动态规划。本题和上题几乎一模一样,唯一的区别在于本题顺序不同的序列被视作不同的组合,因此只需要确定遍历顺序时将顺序修改为先遍历背包容量后遍历物品即可。

由于本题有测试案例会超过int表示范围的情况,因此在内层循环的判断语句还要加上判断条件dp[i] < INT_MAX - dp[i - nums[j]]。

代码:

class Solution {
public:int combinationSum4(vector<int>& nums, int target) {vector<int> dp(target + 1, 0);      //dp[i]表示从数组中任取数字能达到累加和i的排列个数dp[0] = 1;for (int i = 0; i <= target; i++)           //遍历累加和for (int j = 0; j < nums.size(); j++)   //遍历数组if (i >= nums[j] && dp[i] < INT_MAX - dp[i - nums[j]])      //去处案例超过int表示范围的情况dp[i] += dp[i - nums[j]];return dp[target];}

自我总结:

  •  确定遍历顺序的依据:递推公式,数组内元素是否可重复取以及题干要求的是存在,组合还是排列。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/715809.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos7安装夜莺

一、前期准备 1.1.关闭防火墙&#xff0c;SELINUX systemctl stop firewalld.service systemctl disable firewalld.service setenforce 0 sed -i "s/SELINUXenforcing/SELINUXdisabled/g" /etc/selinux/config查看状态 systemctl status firewalld systemctl sta…

Vue开发实例(三)项目引入Element-UI

项目引入Element-UI 一、引入Element-UI二、注册组件1、vue2使用element-ui2、vue3使用element-ui 三、使用Element组件1、轻微改造2、验证element是否生效 一、引入Element-UI npm i element-ui --save npm install element-ui -S等待安装完成 二、注册组件 1、vue2使用ele…

【Leetcode每日一题】前缀和(难度⭐)(25)

1. 题目解析 题目链接&#xff1a;DP34 【模板】前缀和 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 核心在于计算题目所给区间数组元素和返回即可。 2. 算法原理 为了提高计算效率&#xff0c;我们可以预先计算出一个「前缀…

在github的README.md中插入视频;在github的README.md中添加gif演示动画

最近需要再github中上传项目的源代码&#xff0c;应导师的要求&#xff0c;需要再README中加入对实验视频的展示&#xff0c;但是github的README.md其实就是一个markdown文件&#xff0c;据我的理解这个文件里应该无法直接插入视频吧&#xff1f;&#xff08;如果后续有办法直接…

UE4c++ ConvertActorsToStaticMesh ConvertProceduralMeshToStaticMesh

UE4c ConvertActorsToStaticMesh 创建Edior模块&#xff08;最好是放Editor模块毕竟是编辑器代码&#xff09;创建蓝图函数UBlueprintFunctionLibraryUTestFunctionLibrary.hUTestFunctionLibrary.cpp:.Build.cs 目标:为了大量生成模型&#xff0c;我们把虚幻带有的方法迁移成函…

机器学习_10、集成学习-随机森林

随机森林算法 随机森林&#xff08;Random Forest&#xff09;是一种集成学习方法&#xff0c;特别用于分类、回归和其他任务&#xff0c;它通过构建多个决策树&#xff08;Decision Trees&#xff09;在训练时进行预测&#xff0c;并采用平均或多数投票的方式来提高整体模型的…

【vue】keep-alive清除缓存最简单暴力的方法

项目场景&#xff1a; 场景一&#xff1a; 使用vue开发移动端&#xff0c; 有ABC三个页面&#xff0c;点击A跳转到B&#xff0c;点B跳转到C&#xff1b; 点C返回B&#xff0c;点B返回A。 场景二&#xff1a; 场景一实现之后&#xff0c;会出现这样一个问题&#xff1a; 先从A跳…

LeetCode 每日一题 2024/2/26-2024/3/3

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 2/26 938. 二叉搜索树的范围和2/27 2867. 统计树中的合法路径数目2/28 2673. 使二叉树所有路径值相等的最小代价2/29 2581. 统计可能的树根数目3/1 2369. 检查数组是否存在…

leetcode 热题 100_三数之和

题解一&#xff1a; 双指针遍历&#xff1a;暴力解法的三层遍历会超时&#xff0c;因此需要优化遍历的过程。首先是需要对结果进行去重&#xff0c;这里采用排序跳过重复值的做法&#xff0c;在指针遍历时跳过已经遍历过的相同值。在第一层循环确定第一个值后&#xff0c;剩下两…

模型部署 - onnx 的导出和分析 -(1) - PyTorch 导出 ONNX - 学习记录

onnx 的导出和分析 一、PyTorch 导出 ONNX 的方法1.1、一个简单的例子 -- 将线性模型转成 onnx1.2、导出多个输出头的模型1.3、导出含有动态维度的模型 二、pytorch 导出 onnx 不成功的时候如何解决2.1、修改 opset 的版本2.2、替换 pytorch 中的算子组合2.3、在 pytorch 登记&…

vscode+remote突然无法连接服务器以及ssh连接出问题时的排错方法

文章目录 设备描述状况描述解决方法当ssh连接出问题时的排错方法 设备描述 主机&#xff1a;win11&#xff0c;使用vscode的remote-ssh插件 服务器&#xff1a;阿里云的2C2GUbuntu 22.04 UFIE 状况描述 之前一直使用的是vscode的remote服务&#xff0c;都是能够正常连接服务…

【Qt】界面布局

Qt常用布局 除Qt Designer支持可视化设计和布局界面之外&#xff0c;Qt 提供了代码方式来进行界面布局&#xff0c; 以下是几种常用的界面布局方式&#xff1a; 水平布局&#xff08;QHBoxLayout&#xff09;和垂直布局&#xff08;QVBoxLayout&#xff09;&#xff1a; QHBo…

Redis常用数据结构--Zset

Zset ZADDZCARDZCOUNTZRANGE/ZREVRANGEZRANGEBYSCOREZPOPMAX/ZPOPMINBZPOPMAX/BZPOPMINZRANK/ZREVRANKZSCOREZREMZREMRANGEBYRANKZREMRANGEBYSCOREZINCRBYZINTERSTORE/ZUNIONSTORE内部编码使⽤场景 ZADD 添加或者更新指定的元素以及关联的分数到 zset 中&#xff0c;分数应该符…

如何在 Angular 测试中使用 spy

简介 Jasmine spy 用于跟踪或存根函数或方法。spy 是一种检查函数是否被调用或提供自定义返回值的方法。我们可以使用spy 来测试依赖于服务的组件&#xff0c;并避免实际调用服务的方法来获取值。这有助于保持我们的单元测试专注于测试组件本身的内部而不是其依赖关系。 在本…

空调压缩机补充润滑油的方法

空调压缩机补充润滑油的方法有三种&#xff0c;从吸气截止阀旁边通孔吸入&#xff0c;从加油孔中加入&#xff0c;从曲轴箱下部加入&#xff0c;具体操作步骤如下&#xff1a; 1关闭吸气截止阀&#xff0c;启动压缩机几分钟&#xff0c;将曲轴箱中制冷剂排入冷凝器&#xff0c…

vue2结合electron开发桌面端应用

一、Electron是什么&#xff1f; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 。允许您保持一个 JavaScript 代码代码库并创建可在Windows、macOS和Linux上运行的跨平台应用 。 Electron 经常与 Ch…

scrapy 中间件

就是发送请求的时候&#xff0c;会经过&#xff0c;中间件。中间件会处理&#xff0c;你的请求 下面是代码&#xff1a; # Define here the models for your spider middleware # # See documentation in: # https://docs.scrapy.org/en/latest/topics/spider-middleware.html…

【快速上手ProtoBuf】基本使用

文章目录 1 :peach:初识 ProtoBuf:peach:1.1 :apple:序列化概念:apple:1.2 :apple:ProtoBuf 是什么:apple:1.3 :apple:ProtoBuf 的使用特点:apple: 2 :peach:创建 .proto ⽂件:peach:3 :peach:编译 .proto 文件:peach:3 :peach:序列化与反序列化的使用:peach: 1 &#x1f351;初…

洛谷 2036.PERKET

采用递归法的方式进行题解。 思路&#xff1a;首先我们知道在n种材料当中&#xff0c;我们需要从中选择至少有一种得配料才行。也就是说&#xff0c;我们选择的配料数目是自己决定的&#xff0c;而不是那种组合型得对于你有要求的组合型递归方式。 所以我们会想到用指数型得递…

(五)网络优化与超参数选择--九五小庞

网络容量 网络中神经单元数越多&#xff0c;层数越多&#xff0c;神经网路的拟合能力越强。但是训练速度&#xff0c;难度越大&#xff0c;越容易产生过拟合。 如何选择超参数 所谓超参数&#xff0c;也就是搭建神经网路中&#xff0c;需要我们自己去选择&#xff08;不是通…