代码随想录第三十八天| 322. 零钱兑换 279.完全平方数 139.单词拆分 动态规划:关于多重背包,你该了解这些!

server/2025/2/25 8:41:39/

322. 零钱兑换

题目描述

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

你可以认为每种硬币的数量是无限的。

力扣题目链接

322. 零钱兑换

解题思路

这个问题可以使用动态规划来解决。我们定义一个数组 dp,其中 dp[i] 表示凑成金额 i 所需的最少硬币数量。初始化 dp[0] 为 0,因为凑成金额 0 所需的硬币数量为 0。其他 dp[i] 初始化为 Integer.MAX_VALUE,表示初始状态下无法凑成金额 i

接下来,我们遍历每一种硬币,并更新 dp 数组。对于每一种硬币 coins[i],我们更新所有大于或等于 coins[i] 的金额 j 的最少硬币数量。具体来说,如果 dp[j - coins[i]] 不是初始值(即可以凑成金额 j - coins[i]),那么 dp[j] 可以更新为 min(dp[j], dp[j - coins[i]] + 1)

最后,我们检查 dp[amount] 的值。如果它仍然是 Integer.MAX_VALUE,则返回 -1,表示无法凑成总金额。否则,返回 dp[amount],即凑成总金额所需的最少硬币数量。

代码实现

class Solution {public int coinChange(int[] coins, int amount) {int[] dp = new int[amount+1];for(int i=1; i<amount+1; i++){dp[i] = Integer.MAX_VALUE;}for(int i=0; i<coins.length; i++){for(int j=coins[i]; j<amount+1; j++){if(dp[j-coins[i]] != Integer.MAX_VALUE) {dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);}}}return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];}
}

279. 完全平方数

题目描述

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
给你一个整数 n ,返回和为 n 的完全平方数的最少数量。
完全平方数是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

力扣题目链接

279. 完全平方数

解题思路

这个问题同样可以使用动态规划来解决。我们定义一个数组 dp,其中 dp[i] 表示组成和为 i 的完全平方数的最少数量。初始化 dp[0] 为 0,因为组成和为 0 的完全平方数的最少数量为 0。其他 dp[i] 初始化为 Integer.MAX_VALUE,表示初始状态下无法组成和为 i。
接下来,我们遍历所有的完全平方数,并更新 dp 数组。对于每一个完全平方数 ii,我们更新所有大于或等于 ii 的和 j 的最少完全平方数数量。具体来说,如果 dp[j - ii] 不是初始值(即可以组成和为 j - ii),那么 dp[j] 可以更新为 min(dp[j], dp[j - i*i] + 1)。
最后,我们返回 dp[n],即组成和为 n 的完全平方数的最少数量。

代码实现

class Solution {public int numSquares(int n) {int max = Integer.MAX_VALUE;int[] dp = new int[n+1];for(int i=1; i<n+1; i++){dp[i] = max;}dp[0] = 0;for(int i=1; i*i<=n; i++){for(int j=i*i; j<n+1; j++){dp[j] = Math.min(dp[j], dp[j - i*i] + 1);}}return dp[n];}
}

139. 单词拆分

题目描述

给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:

  • 拆分时可以重复使用字典中的单词。
  • 你可以假设字典中没有重复的单词。

力扣题目链接

139. 单词拆分

解题思路

这个问题可以使用动态规划来解决。我们定义一个布尔数组 valid,其中 valid[i] 表示字符串 s 的前 i 个字符是否可以由字典中的单词组成。

  1. 初始化 valid[0]true,因为一个空字符串总是可以被拆分(不需要任何单词)。
  2. 遍历字符串 s 的每一个位置 i,对于每一个位置,我们再遍历它的每一个可能的前缀 j
  3. 如果 s.substring(j, i) 是字典中的一个单词,并且 valid[j]true,那么我们可以说 s.substring(0, i) 也可以被拆分,因此我们将 valid[i] 设置为 true
  4. 最后,valid[s.length()] 将告诉我们整个字符串 s 是否可以被拆分。

代码实现

class Solution {public boolean wordBreak(String s, List<String> wordDict) {HashSet<String> set = new HashSet<>(wordDict);boolean[] valid = new boolean[s.length() + 1];valid[0] = true;for (int i = 1; i <= s.length(); i++) {for (int j = 0; j < i && !valid[i]; j++) {if (set.contains(s.substring(j, i)) && valid[j]) {valid[i] = true;}}}return valid[s.length()];}
}

56. 携带矿石资源(第八期模拟笔试)

题目描述

你是一名宇航员,即将前往一个遥远的行星。在这个行星上,有许多不同类型的矿石资源,每种矿石都有不同的重要性和价值。你需要选择哪些矿石带回地球,但你的宇航舱有一定的容量限制。

给定一个宇航舱,最大容量为 C。现在有 N 种不同类型的矿石,每种矿石有一个重量 w[i],一个价值 v[i],以及最多 k[i] 个可用。不同类型的矿石在地球上的市场价值不同。你需要计算如何在不超过宇航舱容量的情况下,最大化你所能获取的总价值。

输入描述

输入共包括四行,第一行包含两个整数 C 和 N,分别表示宇航舱的容量和矿石的种类数量。

接下来的三行,每行包含 N 个正整数。具体如下:

  • 第二行包含 N 个整数,表示 N 种矿石的重量。
  • 第三行包含 N 个整数,表示 N 种矿石的价格。
  • 第四行包含 N 个整数,表示 N 种矿石的可用数量上限。

解题思路

这个问题是一个典型的多重背包问题,可以通过动态规划来解决。我们可以使用一个一维数组 dp 来表示在不同容量下的最大价值。数组的索引表示当前背包的容量,而值表示在该容量下能够获得的最大价值。

  1. 初始化 dp 数组,所有值设为 0,因为开始时背包中没有物品,价值为 0。
  2. 遍历每一种矿石,对于每一种矿石,再遍历其数量上限。
  3. 对于每一种数量,使用完全背包的思路,更新 dp 数组。
  4. 最后,dp[bagWeight] 将包含最大价值。

代码实现

import java.util.Scanner;
class multi_pack{public static void main(String [] args) {Scanner sc = new Scanner(System.in);int bagWeight, n;bagWeight = sc.nextInt();n = sc.nextInt();int[] weight = new int[n];int[] value = new int[n];int[] nums = new int[n];for (int i = 0; i < n; i++) weight[i] = sc.nextInt();for (int i = 0; i < n; i++) value[i] = sc.nextInt();for (int i = 0; i < n; i++) nums[i] = sc.nextInt();int[] dp = new int[bagWeight + 1];for (int i = 0; i < n; i++) {for (int j = bagWeight; j >= weight[i]; j--) {for (int k = 1; k <= nums[i] && (j - k * weight[i]) >= 0; k++) {dp[j] = Math.max(dp[j], dp[j - k * weight[i]] + k * value[i]);}}}System.out.println(dp[bagWeight]);}
}

http://www.ppmy.cn/server/170518.html

相关文章

跟着李沐老师学习深度学习(十四)

注意力机制&#xff08;Attention&#xff09; 引入 心理学角度 动物需要在复杂环境下有效关注值得注意的点心理学框架&#xff1a;人类根据随意线索和不随意线索选择注意力 注意力机制 之前所涉及到的卷积、全连接、池化层都只考虑不随意线索而注意力机制则显示的考虑随意…

解锁健康密码,拥抱养生生活

在快节奏的现代生活中&#xff0c;健康养生愈发成为人们追求美好生活的关键。步入 2025 年&#xff0c;让我们从日常细节入手&#xff0c;开启一场充满活力的健康养生之旅。 饮食是养生的基石。一日三餐&#xff0c;合理搭配最为重要。多吃谷物杂粮&#xff0c;它们富含膳食纤维…

智能合约的部署

https://blog.csdn.net/qq_40261606/article/details/123249473 编译 点击图中的 “Compile 1_Storage.sol” 存和取一个数的合约&#xff0c;remix自带 pragma solidity >0.8.2 <0.9.0; /*** title Storage* dev Store & retrieve value in a variable* custom:d…

CSS编程基础学习

1. CSS 简介 1.1. CSS概念及作用 HTML即超文本标记语言&#xff08;HyperText Markup Language&#xff09;&#xff0c;是网页制作的基础&#xff0c;通过HTML&#xff0c;开发者可以定义网页的标题、段落、链接、图像、列表、表格、表单等元素。引入CSS 可以针对 HTML 里的…

Linux驱动之tty子系统(简要分析以及驱动实现)

Linux驱动之tty子系统 深入linux源码探究&#xff01; 1. TTY 子系统概述 在 Linux 内核中&#xff0c;TTY (Teletype) 子系统是 用户空间与字符设备交互的桥梁&#xff0c;它最早用于模拟电传打字机&#xff08;Teletype&#xff09;&#xff0c;但如今主要用于 终端、串口…

MySQL 的存储引擎有哪些?它们之间有什么区别?

目录 1. 在事务安全方面 ACID 的具体含义 MySQL 中 ACID 的实现 ACID 的实际应用 总结 2. 在锁机制方面 3. 在外键支持方面 4. 在索引方面 5. 在数据存储方式上 MySQL 目前使用得比较多的版本是 MySQL5.7 和 MySQL8.0。MySQL5.7 和 MySQL 8.0 都支持多种存储引擎&#…

八大经典排序算法

八大经典排序算法 目录 算法概览算法详解 冒泡排序选择排序插入排序希尔排序归并排序快速排序堆排序计数排序 性能对比 1. 算法概览 排序算法平均时间复杂度空间复杂度稳定性排序方式冒泡排序O(n)O(1)稳定In-place选择排序O(n)O(1)不稳定In-place插入排序O(n)O(1)稳定In-pla…

论文略:ACloser Look into Mixture-of-Experts in Large Language Models

202406 arxiv 关于这几个MOE的详细实验 主要实验发现&#xff1a; Mixtral可能包含具有独特属性的专家DeepSeek和Grok的专家权重矩阵的相似性通常低于Mixtral&#xff08;DeepSeek和Grok专家的矩阵级相似性通常接近零&#xff0c;而Mixtral专家的相似性平均约为0.3&#xff09…