《dp補卡——完全背包問題》

在這里插入圖片描述
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]);}
}

內嵌的循環是從大到小遍歷,為了保證每個物品僅僅被添加一次。而完全背包的物品是可以添加多次的,所以要從小到大去遍歷。

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]);}
}

leetcode題目

        • [518. 零錢兌換 II](https://leetcode-cn.com/problems/coin-change-2/)
        • [377. 組合總和 Ⅳ](https://leetcode-cn.com/problems/combination-sum-iv/)
        • 爬樓梯變形
        • [322. 零錢兌換](https://leetcode-cn.com/problems/coin-change/)
        • [279. 完全平方數](https://leetcode-cn.com/problems/perfect-squares/)
        • [139. 單詞拆分](https://leetcode-cn.com/problems/word-break/)

518. 零錢兌換 II

這一題與https://blog.csdn.net/qq_42604176/article/details/116051902?spm=1001.2014.3001.550101背包中的組合問題有相似之處。只需要把遍歷順序修改就行了。
step1: dp[j]:湊成總金額j的貨幣組合數為dp[j]
step2: dp[j] += dp[j - coins[i]];
step3: 湊成總金額0的貨幣組合數為1。
step4:使用完全背包的遍歷方式,注意由于是求組合數,內外嵌套需要注意。

AC代碼如下:

class Solution {
public:int change(int amount, vector<int>& coins) {int sum = 0;vector<int> 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-coins[i]];}}return dp[amount];}
};

代碼隨想錄公眾號做出的這個總結很好,雖然現在還沒有完全理解是為什么:
如果求組合數就是外層for循環遍歷物品,內層for遍歷背包。
如果求排列數就是外層for遍歷背包,內層for循環遍歷物品。

377. 組合總和 Ⅳ

如果本題要把排列都列出來的話,只能使用回溯算法爆搜。
但是它只要求我們得到排列方法的數目。由于可以重復取,所以使用完全背包。由于是求排列數,外層for循環遍歷背包,內層for循環遍歷元素。
最內層需要對兩個數相加小于INT_MAX進行限制。

class Solution {
public:int combinationSum4(vector<int>& nums, int target) {vector<int> dp(target+1,0);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]])dp[i] += dp[i-nums[j]];  }}return dp[target];}
};

爬樓梯變形

假設你正在爬樓梯。需要 n 階你才能到達樓頂。每次可以爬 1 、 2或者m 個臺階。問有多少種不同的方法可以爬到樓頂呢?
分析:1階,2階,m階就是物品,樓頂就是背包。每一階可以重復使用,例如跳了1階,還可以繼續跳1階。所以這是一個完全背包問題。
step1 : dp[i]爬到有i個臺階的樓頂,有dp[i]種方法。

step2: dp[i] += dp[i-j];

step3: dp[0] = 1,dp[…]=0;

step4:遍歷順序,由于是排列問題,1、2與2、1是不一樣的,所以將背包容量放在外層循環,將物品放到內層循環。又因為是完全背包問題,所以從前向后遍歷。

int climbStairs(int n,int m)
{vector<int> dp(n+1,0);dp[0]=1;for(int i = 0; i <= n; i++){for(int j = 0; j <= m; j++)if(i -j >= 0) dp[i] += dp[i-j];}return dp[n];
}

322. 零錢兌換

step1:dp[j]湊足金額為j所需要的錢幣的最少個數為dp[j]
step2:dp[j] = min(dp[j-coins[i]]+1,dp[j]);
step3:湊足金額為0的所需金幣個數為0,即dp[0]=0;其他初值為INT_MAX。
湊足金額為j-coins[i]的最少個數為dp[j-coins[i]],那么只需要加上一個錢幣coins[i]即dp[j-coins[i]]+1就是dp[j].
step4:求最小個數,錢幣有順序無順序都可以,都不影響錢幣的最小個數。
求組合數,for外層遍歷物體,for內層遍歷背包。求排列,外層for遍歷背包,內層for循環遍歷物品。
本題兩者均可。

class Solution {
public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount+1,INT_MAX);dp[0] = 0;for(int i = 0; i < coins.size(); i++)	//物品{for(int j = coins[i]; j <= amount; j++)	//背包容量{//如果為初值,跳過,沒有必要計算,而且計算會溢出if(dp[j-coins[i]] == INT_MAX) continue;dp[j] = min(dp[j-coins[i]]+1,dp[j]);}}//如果沒有被賦值,那么說明沒有解,返回-1if(dp[amount] == INT_MAX) return -1;return dp[amount];}
};

279. 完全平方數

完全平方數就是物品(無限使用),湊成的正整數n就是背包。問湊滿背包最少有多少個物品。
step1:dp[j],湊滿容量為j的背包最少物品數目。
step2:dp[j] = min(dp[j-i*i] +1,dp[j]);
step3: dp[0] = 0;雖然0符合完全平方數要求,但是題目要求是從1開始找完全平方數。其余下標的dp初始值為INT_MAX
step4:對于求最小方法數的,內外層不需要管循環。

class Solution {
public:int numSquares(int n) {vector<int> dp(n+1,INT_MAX);dp[0] = 0;for(int i = 1; i <= n; i++){for(int j = i*i; j <= n; j++){if(dp[j-i*i] == INT_MAX) continue;dp[j] = min(dp[j-i*i]+1,dp[j]);}}return dp[n];}
};

139. 單詞拆分

物品:wordDict中的string,可以重復取
背包:s字符串
step1: dp[i]:字符串長度為i,dp[i]為true,表示可以拆分一個或者多個在字典中出現的單詞。
step2: 如果dp[j]為true,則[j,i]這個區間的子串出現在字典里,那么dp[i]一定為true。
所以遞推公式為;

if(wordSet.find(s.substr(j,i-j)) != wordSet.end() && dp[j]) dp[i] = true;

step3:dp[0]字符串為0,為了方便推導公式,我們只好給他true,不然公式推導下去全為false。
step4:由于是求最小方法數,所以內外層遍歷順序無需在意

class Solution {
public:bool wordBreak(string s, vector<string>& wordDict) {//將vector放入set中,加快查詢unordered_set<string> wordSet(wordDict.begin(),wordDict.end());vector<bool> dp(s.size()+1,false);dp[0] = true;for(int i = 0; i <= s.size(); i++)  //背包容量{for(int j = 0; j <= i; j++)           //物品{string str = s.substr(j,i-j);  if(wordSet.find(str) != wordSet.end() && dp[j] == true){dp[i] = true;}}}return dp[s.size()];}
};

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

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

相關文章

Java中的類型轉換

類型轉換 (Typecasting) Typecasting is a term which is introduced in all the language similar to java. Typecasting是一個用與Java類似的所有語言引入的術語。 When we assign primitive datatype to another datatype. 當我們將原始數據類型分配給另一個數據類型時。 I…

讓crash文件中的內存地址變成函數名稱,

假如程序員編譯了inhouse給測試。 如果在測試過程中出現奔潰現象&#xff0c;我想程序員一般會來看Device Log 也就是 crash文件 如果crash文件遇到如下的情況&#xff0c;在重要的地方看不到函數名稱。我想是一件很奔潰的事情。 1 Exception Type: EXC_BAD_ACCESS (SIGSEGV)2…

《dp補卡——多重背包》

多重背包簡介&#xff1a; 有N種物品和一個容量為V的背包。第i種物品最多有Mi件可用&#xff0c;每件耗費的空間為Ci&#xff0c;價值為Wi。求解將哪些物品裝入背包可使得這些物品耗費的空間總和不超過背包容量&#xff0c;且價值總和最大。 將Mi件攤開&#xff0c;就是一個01背…

kafka消息確認ack_什么是確認(ACK)? ACK代表什么?

kafka消息確認ackACK&#xff1a;致謝 (ACK: Acknowledgment) An acknowledgment (ACK) is a signal that is passed among the communicating processes, computers, or devices to indicate acknowledgment, or delivery of the message, as a component of a communications…

CocoaAsyncSocket 套接字

CocoaAsyncSocket 套接字 https://github.com/robbiehanson/CocoaAsyncSocket Asynchronous socket networking library for Mac and iOS 用于iOS以及Mac的異步套接字網絡庫。 TCP GCDAsyncSocket and AsyncSocket are TCP/IP socket networking libraries. Here are the key…

谷歌瀏覽器設置緩存方法

谷歌瀏覽器設置緩存方法&#xff1a; 1、在桌面Google Chrome快捷方式&#xff0c;目標&#xff1a;找到 C:\Users\Splendid\AppData\Local\…\Application\chrome.exe 在這后面加上-Disk-Cache-Dir”Z:\TEMP” 注意: -Disk前面有空格&#xff0c;”Z:\TEMP” 是文件存放在Z盤T…

《dp補卡——買賣股票問題》

目錄121. 買賣股票的最佳時機貪心dp思路滾動數組優化122. 買賣股票的最佳時機 II123. 買賣股票的最佳時機 III188. 買賣股票的最佳時機 IV309. 最佳買賣股票時機含冷凍期714. 買賣股票的最佳時機含手續費121. 買賣股票的最佳時機 貪心 取最左最小值&#xff0c;取最右最大值&…

oo0ooo0ooo0oo_OoO的完整形式是什么?

oo0ooo0ooo0ooOoO&#xff1a;外出 (OoO: Out of Office) OoO is an abbreviation of "Out of Office". OoO是“不在辦公室”的縮寫。 It is an expression, which is commonly used in the Gmail platform. It is written in the body or the subject of the email…

SP2010開發和VS2010專家食譜--第三章節--高級工作流(2)--為沙盒解決方案創建自定義活動...

盡管沙河解決方案功能有限&#xff0c;你仍然可以開發自定義活動&#xff0c;在SharePoint Designer中使用而不用改變web.config或添加.ACTION文件到根文件夾。 轉載于:https://www.cnblogs.com/crazygolf/p/3856795.html

sql where 1=1和 0=1 的作用

where 11; 這個條件始終為True&#xff0c;在不定數量查詢條件情況下&#xff0c;11可以很方便的規范語句。 一、不用where 11 在多條件查詢中的困擾 舉個例子&#xff0c;如果您做查詢頁面&#xff0c;并且&#xff0c;可查詢的選項有多個&#xff0c;同時&#xff0c;還讓用戶…

j@2ff4f00f_J4F的完整形式是什么?

j2ff4f00fJ4F&#xff1a;只是為了好玩 (J4F: Just For Fun) J4F is an abbreviation of "Just For Fun". J4F是“ Just For Fun”的縮寫 。 It is an expression, which is commonly used in messaging or chatting on social media networking sites like Faceboo…

《dp補卡——子序列問題》

目錄300. 最長遞增子序列674. 最長連續遞增序列718. 最長重復子數組1143. 最長公共子序列53. 最大子序和392. 判斷子序列115. 不同的子序列583. 兩個字符串的刪除操作72. 編輯距離647. 回文子串 &#xff08;與 5.最長回文子串思路差不多&#xff09;516. 最長回文子序列300. 最…

[LeetCode] Maximal Rectangle

Given a 2D binary matrix filled with 0s and 1s, find the largest rectangle containing all ones and return its area. 在做 Largest Rectangle in Histogram的時候有人說可以用在這題&#xff0c;看了一下還真是&#xff0c;以每行為x軸&#xff0c;每列往上累計的連續的…

什么是alpha測試_什么是ALPHA?

什么是alpha測試Α (ALPHA) Alpha is the first and foremost letter of the Greek alphabet. In the classification of Greek numerals or numbers, it constitutes a value of 1. Alpha是希臘字母的第一個也是最重要的字母 。 在希臘數字或希臘數字的分類中&#xff0c;它的…

《leetcode : 647. 回文子串 思考分析雙指針解法》

647. 回文子串 如何確定是回文串&#xff1a; 找中心然后往兩邊擴散&#xff0c;判斷是否對稱即可。 在遍歷中心點的時候&#xff0c;注意中心點可以是一個元素也可以是兩個元素。 class Solution { public:int cal_two_extend(const string& s,int i,int j,int n){int re…

天草初級班(3)

算術運算指令算術運算指令是反映CPU計算能力的一組指令&#xff0c;也是編程時經常使用的一組指令。它包括&#xff1a;加、減、乘、除及其相關的輔助指令。 該組指令的操作數可以是8位、16位和32位(80386)。當存儲單元是該類指令的操作數時&#xff0c;該操作數的尋址方式可以…

4.3.3版本之引擎bug

bug描述&#xff1a;   IOS設備上&#xff0c;當使用WWW www WWW.LoadFromCacheOrDownload(url, verNum); 下載資源時&#xff0c;第一次下載某個資源&#xff0c;www.assetBundle必定為空。 解決辦法&#xff1a;   引擎版本降到4.3.2或者升到4.3.4或更高。 這個bug絕對是…

sml完整形式_411的完整形式是什么?

sml完整形式411&#xff1a;信息 (411: Information) 411 is an abbreviation of “Information". 411是“信息”的縮寫 。 It is an expression, which is commonly used in messaging or chatting on social media networking sites like Facebook, Yahoo Messenger, a…

php 檢測用戶是否關閉瀏覽器

1、例子1 echo str_repeat(" ",3000);ignore_user_abort(true); mylog(online);while (true) {/** 1、程序正常結束 connection_status 0* 2、點擊瀏覽器“停止”按鈕 connection_status 1* 3、超時 connection_status 2*/echo "test<br>\n&qu…

explain用法

explain用法 EXPLAIN SELECT …… 變體&#xff1a; 1. EXPLAIN EXTENDED SELECT …… 將執行計劃“反編譯”成SELECT語句&#xff0c;運行SHOW WARNINGS 可得到被MySQL優化器優化后的查詢語句 2. EXPLAIN PARTITIONS SELECT …… 用于分區表的EXPLAIN 執行計劃包含的信息 id…