代码训练营 day42|LeetCode 518,LeetCode 377,LeetCode 70

news/2024/10/23 1:50:05/

前言

这里记录一下陈菜菜的刷题记录,主要应对25秋招、春招
个人背景
211CS本+CUHK计算机相关硕,一年车企软件开发经验
代码能力:有待提高
常用语言:C++

系列文章目录

第42天 :第九章 动态规划 part05


`

文章目录

  • 前言
  • 系列文章目录
    • 第42天 :第九章 动态规划 part05
  • 一、今日任务
  • 二、详细布置
      • 损失
      • 518.零钱兑换II
        • 提示:
        • 样例1:
        • 思路
        • 实战
        • 踩坑
      • 377. 组合总和 Ⅳ
        • 提示:
        • 样例1:
        • 思路
        • 实战
        • 踩坑
      • 70. 爬楼梯(进阶版)
        • 提示:
        • 样例1:
        • 思路
        • 实战
    • 总结



一、今日任务

● 完全背包
● 518. 零钱兑换 II
● 377. 组合总和 Ⅳ
● 70. 爬楼梯 (进阶)

二、详细布置

损失

文章讲解:代码随想录

有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。

完全背包和01背包问题唯一不同的地方就是,每种物品有无限件。
01背包的核心代码:

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

01背包内嵌的循环是从大到小遍历,为了保证每个物品仅被添加一次
而完全背包的物品是可以添加多次的,所以要从小到大去遍历

// 先遍历物品,再遍历背包
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]);}
}

01背包中二维dp数组的两个for遍历的先后循序是可以颠倒,一维dp数组的两个for循环先后循序一定是先遍历物品,再遍历背包容量。
在完全背包中,对于一维dp数组来说,其实两个for循环嵌套顺序是无所谓的!
代码:

// 先遍历物品,在遍历背包
void test_CompletePack() {vector<int> weight = {1, 3, 4};vector<int> value = {15, 20, 30};int bagWeight = 4;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]);}}cout << dp[bagWeight] << endl;
}
int main() {test_CompletePack();
}// 先遍历背包,再遍历物品
void test_CompletePack() {vector<int> weight = {1, 3, 4};vector<int> value = {15, 20, 30};int bagWeight = 4;vector<int> dp(bagWeight + 1, 0);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 << dp[bagWeight] << endl;
}
int main() {test_CompletePack();
}

518.零钱兑换II

题目链接:力扣518
文章讲解:代码随想录

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

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

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

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

提示:

1 <= coins.length <= 300
1 <= coins[i] <= 5000
coins 中的所有值 互不相同
0 <= amount <= 5000

样例1:
输入:amount = 5, coins = [1, 2, 5]
输出:4
解释:有四种方式可以凑成总金额:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1
思路

这题就是完全背包的典型应用。

实战
class Solution {
public:int change(int amount, vector<int>& coins) {vector<uint64_t> dp(amount+1,0);dp[0]=1;for(int i=0;i<coins.size();i++){for(int j=coins[i];j<=amount;j++){dp[j]=dp[j]+dp[j-coins[i]];}}return dp[amount];}
};
踩坑

vector数组的类型是uint64_t,用int会报错。

377. 组合总和 Ⅳ

题目链接:力扣377题链接
文章讲解:图文讲解

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

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

提示:

1 <= nums.length <= 200
1 <= nums[i] <= 1000
nums 中的所有元素 互不相同
1 <= target <= 1000

样例1:
输入:nums = [1,2,3], target = 4
输出:7
解释:
所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
请注意,顺序不同的序列被视作不同的组合。     
思路

这题和上一题类似,不过这题是排列数不是组合数,即把两个循环调换顺序。

实战
class Solution {
public:int combinationSum4(vector<int>& nums, int target) {vector<uint64_t> dp(target+1,0);dp[0]=1;for(int j=0;j<=target;j++){for(int i=0;i<nums.size();i++){if (j - nums[i] >= 0)dp[j]=dp[j]+dp[j-nums[i]];}}return dp[target];}
};
踩坑

if (j - nums[i] >= 0)表示容量为j的袋子至少能装下nums[i]的东西才会更新数组

70. 爬楼梯(进阶版)

题目链接:卡码网57
文章讲解:图文讲解

题目描述

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬至多m (1 <= m < n)个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。
输入:输入共一行,包含两个正整数,分别表示n, m
输出:输出一个整数,表示爬到楼顶的方法数。

提示:

数据范围:
1 <= m < n <= 32;

样例1:
输入:3 2
输出:3
当 m = 2,n = 3 时,n = 3 这表示一共有三个台阶,m = 2 代表你每次可以爬一个台阶或者两个台阶。此时你有三种方法可以爬到楼顶。1+ 1+ 1 阶段
1+ 22+ 1
思路

抽象成完全背包问题,而且是排列数。

实战
#include<vector>
#include <iostream>
using namespace std;
int main(){int m,n;cin>>n>>m;vector<int> dp(n+1,0);vector<int> M(m,0);for(int i=0;i<m;i++){M[i]=i+1;}dp[0]=1;//dp[1]=1;for(int j=0;j<=n;j++){for(int i=0;i<m;i++){if(j>=M[i])dp[j]=dp[j]+dp[j-M[i]];}}cout<<dp[n]<<endl;return 0;
}

总结

今天主要学习了dp的一系列操作,完全背包问题容易理解。
加油,坚持打卡的第42天。


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

相关文章

软考-软件设计师(10)-专业英语词汇汇总与新技术知识点

场景 以下为高频考点、知识点汇总。 软件设计师上午选择题知识点、高频考点、口诀记忆技巧、经典题型汇总: 软考-软件设计师(1)-计算机基础知识点:进制转换、数据编码、内存编址、串并联可靠性、海明校验码、吞吐率、多媒体等: 软考-软件设计师(1)-计算机基础知识点:进制…

优选算法第一讲:双指针模块

优选算法第一讲&#xff1a;双指针模块 1.移动零2.复写零3.快乐数4.盛最多水的容器5.有效三角形的个数6.查找总价格为目标值的两个商品7.三数之和8.四数之和 1.移动零 链接: 移动零 下面是一个画图&#xff0c;其中&#xff0c;绿色部分标出的是重点&#xff1a; 代码实现&am…

PHP中的ReflectionClass常见用法

ReflectionClass是 PHP 中的一个类&#xff0c;它提供了有关类的信息的反射。 使用ReflectionClass可以在运行时获取关于类的各种信息&#xff0c;例如类的名称、方法、属性、注释等。 以下是一些常见的用法&#xff1a; 获取类的名称&#xff1a; $reflection new Reflec…

The 2021 CCPC Weihai Onsite A,D,J

A - Goodbye, Ziyin! 题意: 给定一个树的点数和边,问以每个点为根节点,有多少个树为二叉树 思路: 按照入度来算,但凡出现入度>4的一定不能形成二叉树,入度<2的拎起来之后可以作为根 int n,m,k,q[N]; void solve(){cin>>n;_for(i,n-1){cin>>k;q[k];cin&g…

【慕伏白教程】将 Windows11 装进口袋 -- 便携式 Windows 11 制作教程

目录 下载 Windows 11 镜像下载 Rufus开始安装 Windows 11 下载 Windows 11 镜像 打开微软 Windows 11 官方下载网站&#xff0c;找到 下载适用于 x64 设备的 Windows 11 磁盘映像 (ISO) 根据个人情况选择要下载的磁盘镜像&#xff0c;选择多版本 ISO 的话可在安装系统开始时进…

探索 Python 幽默之源:pyjokes 库全解析

&#x1f680; 探索 Python 幽默之源&#xff1a;pyjokes 库全解析 1. 背景介绍&#xff1a;为何选择 pyjokes&#xff1f; 在紧张的编程工作中&#xff0c;幽默是一种有效的缓解压力的方式。pyjokes 是一个专为程序员设计的 Python 库&#xff0c;它提供了丰富的单行笑话&am…

【JavaEE初阶】网络编程TCP协议实现回显服务器以及如何处理多个客户端的响应

前言 &#x1f31f;&#x1f31f;本期讲解关于TCP/UDP协议的原理理解~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废话不多说…

Torch模型导入

冻结param的3种方式 for param in net.lstm.parameters():param.requires_grad Truenet.lstm.requires_grad True # 无效net.lstm.state_dict()[weight_ih_l0].requires_gradFalsenet.lstm.weight_ih_l0.requires_grad False# dir(net.lstm) to validate attributes …