第四十四天| 卡爾網 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.pswp.cn/news/715809.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/715809.shtml
英文地址,請注明出處:http://en.pswp.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;不是通…