代碼隨想錄算法訓練營第三十天 | 卡碼網46.攜帶研究材料(二維解法)、卡碼網46.攜帶研究材料(滾動數組)、LeetCode416.分割等和子集

代碼隨想錄算法訓練營第三十天 | 卡碼網46.攜帶研究材料(二維解法)、卡碼網46.攜帶研究材料(滾動數組)、LeetCode416.分割等和子集

01-1 卡碼網46.攜帶研究材料(二維)

相關資源

  • 題目鏈接:46. 攜帶研究材料

  • 文章講解:01背包二維問題

  • 視頻講解:0-1背包問題

題目:

小明是一位科學家,他需要參加一場重要的國際科學大會,以展示自己的最新研究成果。他需要帶一些研究材料,但是他的行李箱空間有限。這些研究材料包括實驗設備、文獻資料和實驗樣本等等,它們各自占據不同的空間,并且具有不同的價值。

小明的行李空間為 N,問小明應該如何抉擇,才能攜帶最大價值的研究材料,每種研究材料只能選擇一次,并且只有選與不選兩種選擇,不能進行切割。

第一想法:我之前是接觸過01背包問題的,但現在一點思路也沒有

看完代碼隨想錄之后的想法

五部曲

  1. dp數組的含義:dp[i][j]表示從下標為[0-i]的物品里任意取,放進容量為j的背包,價值總和最大是多少
  2. 確定遞推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])
  3. 初始化dp數組,dp[i][0]=0,當 j < weight[0]的時候,dp[0][j] 是 0,因為背包容量比編號0的物品重量還小。當j >= weight[0]時,dp[0][j]應該是value[0],因為背包容量放足夠放編號0物品。
  4. 確定遍歷順序,先遍歷物品和先遍歷背包重量都可以,因為均由左上角推導得到
  5. 打印dp數組

實現

#include <bits/stdc++.h>
using namespace std;int main() {int n, bagweight;// bagweight代表行李箱空間cin >> n >> bagweight;vector<int> weight(n, 0); // 存儲每件物品所占空間vector<int> value(n, 0);  // 存儲每件物品價值for(int i = 0; i < n; ++i) {cin >> weight[i];}for(int j = 0; j < n; ++j) {cin >> value[j];}// dp數組, dp[i][j]代表行李箱空間為j的情況下,從下標為[0, i]的物品里面任意取,能達到的最大價值vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));// 初始化, 因為需要用到dp[i - 1]的值// j < weight[0]已在上方被初始化為0// j >= weight[0]的值就初始化為value[0]for (int j = weight[0]; j <= bagweight; j++) {dp[0][j] = value[0];}for(int i = 1; i < weight.size(); i++) { // 遍歷科研物品for(int j = 0; j <= bagweight; j++) { // 遍歷行李箱容量if (j < weight[i]) dp[i][j] = dp[i - 1][j]; // 如果裝不下這個物品,那么就繼承dp[i - 1][j]的值else {dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);}}}cout << dp[n - 1][bagweight] << endl;return 0;
}

ToDo:自己寫出來

2025-3-3:

#include <bits/stdc++.h>
using namespace std;
int main(){int M, N;cin >> M >> N;vector<int> weight(M,0);vector<int> value(M,0);for(int i = 0; i < M; i++){cin >> weight[i];}for(int j = 0; j < M; j++){cin >> value[j];}// 初始化vector<vector<int>> dp(weight.size(),vector<int>(N+1,0));for(int j = weight[0]; j<= N; j++){dp[0][j] = value[0];} for(int i = 1; i < M; i++){for(int j = 0; 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]);}}}cout << dp[M - 1][N] << endl;
}
01-2 卡碼網46.攜帶研究材料(一維)

相關資源

  • 題目鏈接:46. 攜帶研究材料

  • 文章講解:01背包問題一維

  • 視頻講解:01背包問題(滾動數組篇)

題目:

小明是一位科學家,他需要參加一場重要的國際科學大會,以展示自己的最新研究成果。他需要帶一些研究材料,但是他的行李箱空間有限。這些研究材料包括實驗設備、文獻資料和實驗樣本等等,它們各自占據不同的空間,并且具有不同的價值。

小明的行李空間為 N,問小明應該如何抉擇,才能攜帶最大價值的研究材料,每種研究材料只能選擇一次,并且只有選與不選兩種選擇,不能進行切割。

看完代碼隨想錄之后的想法

五部曲

  1. dp數組的含義:dp[j]表示:容量為j的背包,所背的物品價值可以最大為dp[j]
  2. 確定遞推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
  3. 初始化dp數組,dp數組初始化的時候,都初始為0就可以了
  4. 確定遍歷順序,先遍歷物品再遍歷背包重量,并且要求背包容量由大到小遍歷,從而保證物品i只被放入一次
  5. 打印數組

實現

// 一維dp數組實現
#include <iostream>
#include <vector>
using namespace std;int main() {// 讀取 M 和 Nint M, N;cin >> M >> N;vector<int> costs(M);vector<int> values(M);for (int i = 0; i < M; i++) {cin >> costs[i];}for (int j = 0; j < M; j++) {cin >> values[j];}// 創建一個動態規劃數組dp,初始值為0vector<int> dp(N + 1, 0);// 外層循環遍歷每個類型的研究材料for (int i = 0; i < M; ++i) {// 內層循環從 N 空間逐漸減少到當前研究材料所占空間for (int j = N; j >= costs[i]; --j) {// 考慮當前研究材料選擇和不選擇的情況,選擇最大值dp[j] = max(dp[j], dp[j - costs[i]] + values[i]);}}// 輸出dp[N],即在給定 N 行李空間可以攜帶的研究材料最大價值cout << dp[N] << endl;return 0;
}

ToDo:復刻

2025-3-3:

#include <bits/stdc++.h>
using namespace std;
int main(){int M, N;cin >> M >> N;vector<int> weight(M,0);vector<int> value(M,0);for(int i = 0; i < M; i++){cin >> weight[i];}for(int j = 0; j < M; j++){cin >> value[j];}// 初始化vector<int> dp(N+1,0);for(int i = 0; i < M; i++){for(int j = N; j >= weight[i]; j--){dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}}cout << dp[N] << endl;
}

感悟:其實從前往后還是從后往前遍歷很好想,二維遍歷過程可以發現,當前的dp[i][j] 來自于上方正對和上方偏左,如果一維滾動數組從前往后遍歷,前面的發生改變,后面的就會被影響;至于為什么先遍歷物品,再遍歷背包容量,假如順序顛倒過來,其實可以還原成二維遍歷過程,因為二維遍歷的從上往下再從左往右,當前單元格其實是用到了當前單元格的上一個單元格,并不能豎著拷貝(要想這樣,除非dp[i][j] = max(dp[i][j-1], dp[i - weight[j]+value[j]][j - 1),換句話說i和j是不可對調等價的)

01-3 LeetCode416.分割等和子集

相關資源

  • 題目鏈接:416. 分割等和子集

  • 文章講解:分割等和子集

  • 視頻講解:LeetCode:416.分割等和子集

題目:

給你一個 只包含正整數非空 數組 nums 。請你判斷是否可以將這個數組分割成兩個子集,使得兩個子集的元素和相等。

第一想法:這個想不出來和01背包有關系

看完代碼隨想錄之后的想法

問題轉化:

首先,本題要求集合里能否出現總和為 sum / 2 的子集。既有一個 只能裝重量為 sum / 2 的背包,商品為數字,這些數字能不能把 這個背包裝滿。那每一件商品是數字的話,對應的重量 和 價值是多少呢?一個數字只有一個維度,即 重量等于價值。當數字 可以裝滿 承載重量為 sum / 2 的背包的背包時,這個背包的價值也是 sum / 2。那么這道題就是 裝滿 承載重量為 sum / 2 的背包,價值最大是多少?如果最大價值是 sum / 2,說明正好被商品裝滿了

動規五部曲分析如下:

  1. 確定dp數組以及下標的含義:01背包中,dp[j] 表示: 容量(所能裝的重量)為j的背包,所背的物品價值最大可以為dp[j]

  2. 確定遞推公式:dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])

  3. 初始化:為0

  4. 遍歷順序:一維dp數組,物品遍歷的for循環放在外層,遍歷背包的for循環放在內層,且內層for循環倒序遍歷

  5. 打印數組

實現:

class Solution {
public:bool canPartition(vector<int>& nums) {int sum = 0;// dp[i]中的i表示背包內總和// 題目中說:每個數組中的元素不會超過 100,數組的大小不會超過 200// 總和不會大于20000,背包最大只需要其中一半,所以10001大小就可以了vector<int> dp(10001, 0);for (int i = 0; i < nums.size(); i++) {sum += nums[i];}// 也可以使用庫函數一步求和// int sum = accumulate(nums.begin(), nums.end(), 0);if (sum % 2 == 1) return false;int target = sum / 2;// 開始 01背包for(int i = 0; i < nums.size(); i++) {for(int j = target; j >= nums[i]; j--) { // 每一個元素一定是不可重復放入,所以從大到小遍歷dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);}}// 集合中的元素正好可以湊成總和targetif (dp[target] == target) return true;return false;}
};

收獲:題目中物品是nums[i],重量是nums[i],價值也是nums[i],背包體積是sum/2。

ToDo:復現

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72224.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72224.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72224.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

nvidia驅動更新,centos下安裝openwebui+ollama(非docker)

查看centos內核版本 uname -a cat /etc/redhat-release下載對應的程序&#xff08;這個是linux64位版本通用的&#xff09; https://cn.download.nvidia.cn/tesla/550.144.03/NVIDIA-Linux-x86_64-550.144.03.run cudnn想辦法自己下一下&#xff0c;我這里是12.x和11.x通用的…

【AIGC系列】4:Stable Diffusion應用實踐和代碼分析

AIGC系列博文&#xff1a; 【AIGC系列】1&#xff1a;自編碼器&#xff08;AutoEncoder, AE&#xff09; 【AIGC系列】2&#xff1a;DALLE 2模型介紹&#xff08;內含擴散模型介紹&#xff09; 【AIGC系列】3&#xff1a;Stable Diffusion模型原理介紹 【AIGC系列】4&#xff1…

51單片機-串口通信編程

串行口工作之前&#xff0c;應對其進行初始化&#xff0c;主要是設置產生波特率的定時器1、串行口控制盒中斷控制。具體步驟如下&#xff1a; 確定T1的工作方式&#xff08;編程TMOD寄存器&#xff09;計算T1的初值&#xff0c;裝載TH1\TL1啟動T1&#xff08;編程TCON中的TR1位…

Windows 10 遠程桌面連接使用指南

目錄 一、引言 二、準備工作 1、確認系統版本 2、服務器端設置 三、客戶端連接 1、打開遠程桌面連接程序 2、輸入連接信息 3、輸入登錄憑證 4、開始使用遠程桌面 四、移動端連接&#xff08;以 iOS 為例&#xff09; 1、下載安裝應用 2、添加遠程計算機 3、進行連接…

spring boot打包插件的問題

在spring boot項目中聲明了 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build> 執行mvn clean package&…

R語言+AI提示詞:貝葉斯廣義線性混合效應模型GLMM生物學Meta分析

全文鏈接&#xff1a;https://tecdat.cn/?p40797 本文旨在幫助0基礎或只有簡單編程基礎的研究學者&#xff0c;通過 AI 的提示詞工程&#xff0c;使用 R 語言完成元分析&#xff0c;包括數據處理、模型構建、評估以及結果解讀等步驟&#xff08;點擊文末“閱讀原文”獲取完整代…

iOS UICollectionViewCell 點擊事件自動化埋點

iOS 中經常要進行埋點&#xff0c;我們這里支持 UICollectionViewCell. 進行自動化埋點&#xff0c;思路&#xff1a; 通過hook UICollectionViewCell 的setSelected:方法&#xff0c; 則新的方法中執行埋點邏輯&#xff0c;并調用原來的方法 直接上代碼 implementation UICol…

課程《MIT Introduction to Deep Learning》

在Youtubu上&#xff0c;MIT Introduction to Deep Learning (2024) | 6.S191 共8節課&#xff1a; (1) MIT Introduction to Deep Learning (2024) | 6.S191 (2) MIT 6.S191: Recurrent Neural Networks, Transformers, and Attention (3) MIT 6.S191: Convolutional Neural N…

Docker 學習(一)

一、Docker 核心概念 Docker 是一個開源的容器化平臺&#xff0c;允許開發者將應用及其所有依賴&#xff08;代碼、運行時、系統工具、庫等&#xff09;打包成一個輕量級、可移植的“容器”&#xff0c;實現 “一次構建&#xff0c;隨處運行”。 1、容器&#xff08;Container…

007 訂單支付超時自動取消訂單(rabbitmq死信隊列 mybatis)

文章目錄 死信隊列RabbitMQ 配置類 RabbitMQConfig.java生產者 OrderTimeoutProducer.java消費者 OrderTimeoutConsumer.java應用配置 application.ymlpom.xml 依賴實體類 Order.java&#xff08;不變&#xff09;Mapper 接口 OrderMapper.java&#xff08;不變&#xff09;服務…

計算機畢業設計SpringBoot+Vue.js智慧圖書管理系統(源碼+文檔+PPT+講解)

溫馨提示&#xff1a;文末有 CSDN 平臺官方提供的學長聯系方式的名片&#xff01; 溫馨提示&#xff1a;文末有 CSDN 平臺官方提供的學長聯系方式的名片&#xff01; 溫馨提示&#xff1a;文末有 CSDN 平臺官方提供的學長聯系方式的名片&#xff01; 作者簡介&#xff1a;Java領…

《論數據分片技術及其應用》審題技巧 - 系統架構設計師

論數據分片技術及其應用寫作框架 一、考點概述 本論題“論數據分片技術及其應用”主要考察的是軟件工程中數據分片技術的理解、應用及其實際效果分析。考點涵蓋以下幾個方面&#xff1a; 首先&#xff0c;考生需對數據分片的基本概念有清晰的認識&#xff0c;理解數據分片是…

【每日學點HarmnoyOS Next知識】web加載pdf、Toggle禁用、Grid多次渲染問題、Web判斷是否存在title、 List側滑欄關閉

【每日學點HarmnoyOS Next知識】web加載pdf、Toggle禁用、Grid多次渲染問題、Web判斷是否存在title、 List側滑欄關閉 1、HarmonyOS Web組件加載本地pdf文件后&#xff0c;默認顯示標題和下載按鈕&#xff0c;可以隱藏或者有對應的操作這個title的API嗎&#xff1f; 隱藏PDF操…

下載 MindSpore 配置 PyTorch環境

以下是下載 MindSpore 并配置 PyTorch 環境的詳細步驟&#xff0c;適用于常見的 Linux/Windows 系統&#xff08;以 NVIDIA GPU 為例&#xff09;&#xff1a; 一、環境準備 1. 硬件與軟件檢查 GPU 支持&#xff1a;確保使用 NVIDIA 顯卡&#xff0c;通過 nvidia-smi 查看驅動…

三、數據提取

利用 requests 可以獲取網站頁面數據&#xff0c;但是 requests 返回的數據中包含了一些冗余數據&#xff0c;我們需要在這些數據集中提取自己需要的信息。所以我們要學會在數據集中提取自己需要的數據。 需要掌握的知識點如下&#xff1a; json 數據提取 jsonpath 語法 靜態…

Qt | 實戰繼承自QObject的IOThread子類實現TCP客戶端(安全銷毀)

點擊上方"藍字"關注我們 01、QThread >>> start() 啟動線程,調用后會執行 run() 方法。 run() 線程的入口點,子類化 QThread 時需要重寫此方法以定義線程的執行邏輯。 quit() 請求線程退出,線程會在事件循環結束后終止。 exit(int returnCode = 0) 退出…

int new_pos = (pos + delta + 9) % 9 化曲為直算法

公式 int new_pos (pos delta 9) % 9; 是一個常見的 循環數組索引計算 方法&#xff0c;用于處理圓圈排列中的位置計算。這個公式可以總結出一個普遍的規律&#xff0c;適用于任何循環數組或圓圈排列的場景。 普遍規律 假設有一個長度為 ( n ) 的循環數組&#xff08;或圓圈…

生成一個日期時間序列,從‘2024-12-03‘開始,每小時遞增 oracle 轉為達夢

-------------------------------生成一個日期時間序列&#xff0c;從2024-12-03開始&#xff0c;每小時遞增---------------------------- ---原oracle : SELECT to_date(2024-12-03, yyyy-mm-dd) (ROWNUM - 1) / 24 data_time FROM dual CO…

前端學習——HTML

VSCode常用快捷鍵 代碼格式化&#xff1a;ShiftAltF 向上或向下移動一行&#xff1a;AltUp或AltDown 快速復制一行代碼&#xff1a;ShiftAltUp或者ShiftAltDown 快速替換&#xff1a;CtrlH HTML標簽 文本標簽 定義著重文字 定義粗體文字 定義斜體文字 加重語氣 刪除字 無特…

Hadoop之02:MR-圖解

1、不是所有的MR都適合combine 1.1、map端統計出了不同班級的每個學生的年齡 如&#xff1a;(class1, 14)表示class1班的一個學生的年齡是14歲。 第一個map任務&#xff1a; class1 14 class1 15 class1 16 class2 10第二個map任務&#xff1a; class1 16 class2 10 class…