動態規劃~01背包問題

01背包問題
經典的0 - 1背包問題的解決方案。


二維數組的版本

代碼功能概述

0 - 1背包問題指的是有 n 個物品和一個容量為 m 的背包,每個物品有對應的體積 v[i] 和價值 w[i],需要從這些物品里挑選若干個放入背包,讓背包內物品的總價值達到最大。每個物品僅能選擇放入或者不放入背包(即0 - 1選擇)。

代碼詳細解釋

#include<bits/stdc++.h>
using namespace std;// 定義長整型別名
typedef long long LL;
// 定義數組的最大長度
const int N=1100;// f[i][j] 表示前 i 個物品,背包容量為 j 時的最大價值
int f[N][N];
// v[i] 表示第 i 個物品的體積,w[i] 表示第 i 個物品的價值
int v[N],w[N];int main(){// n 表示物品的數量,m 表示背包的容量int n,m;// 從標準輸入讀取物品數量和背包容量cin>>n>>m;// 循環讀取每個物品的體積和價值for(int i = 1;i<=n;i++){cin>>v[i]>>w[i];}// 動態規劃求解過程for(int i = 1;i <= n;i++){for(int j = 1;j <= m;j++){// 如果當前背包容量 j 小于第 i 個物品的體積 v[i],則不能放入第 i 個物品if(j < v[i])// 最大價值等于前 i - 1 個物品在容量 j 下的最大價值f[i][j] = f[i-1][j];else// 可以選擇放入或不放入第 i 個物品,取兩者中的最大值f[i][j] = max(f[i-1][j],f[i-1][j-v[i]]+w[i]);}}// 輸出前 n 個物品,背包容量為 m 時的最大價值cout<<f[n][m];return 0;
}

代碼核心邏輯

  • 狀態定義f[i][j] 代表前 i 個物品,背包容量為 j 時所能獲得的最大價值。
  • 狀態轉移
    • j < v[i],也就是當前背包容量不足以放入第 i 個物品,那么 f[i][j] = f[i - 1][j]
    • j >= v[i],則可以選擇放入或者不放入第 i 個物品:
      • 不放入:f[i][j] = f[i - 1][j]
      • 放入:f[i][j] = f[i - 1][j - v[i]] + w[i]
    • 取這兩種情況的最大值作為 f[i][j] 的值。
  • 最終結果f[n][m] 即為前 n 個物品,背包容量為 m 時的最大價值。

復雜度分析

  • 時間復雜度 O ( n m ) O(nm) O(nm),這里的 n 是物品的數量,m 是背包的容量。
  • 空間復雜度 O ( n m ) O(nm) O(nm),主要是用于存儲狀態數組 f

要將你的二維動態規劃代碼優化為一維數組,可以利用動態規劃的狀態轉移只依賴于上一行的狀態這一特性。通過從右到左更新一維數組,可以避免覆蓋還未使用的狀態,從而實現空間優化。


一維數組的版本

優化后的代碼

#include <bits/stdc++.h>
using namespace std;const int N = 1100;int f[N]; // 一維動態規劃數組,f[j] 表示湊出金額 j 所需的最大價值
int v[N], w[N]; // v[i] 表示第 i 個物品的體積,w[i] 表示第 i 個物品的價值int main() {int n, m;cin >> n >> m; // 輸入物品數量 n 和背包容量 mfor (int i = 1; i <= n; i++) {cin >> v[i] >> w[i]; // 輸入每個物品的體積和價值}// 初始化動態規劃數組memset(f, 0, sizeof(f)); // 初始時,所有金額的最大價值為 0// 動態規劃求解for (int i = 1; i <= n; i++) { // 遍歷每個物品for (int j = m; j >= v[i]; j--) { // 從大到小遍歷背包容量f[j] = max(f[j], f[j - v[i]] + w[i]); // 更新狀態}}// 輸出結果cout << f[m] << endl; // 輸出湊出金額 m 的最大價值return 0;
}

代碼解釋

1. 一維數組的定義
  • 原代碼使用二維數組 f[i][j] 表示前 i 個物品在背包容量為 j 時的最大價值。
  • 優化后,使用一維數組 f[j] 表示背包容量為 j 時的最大價值。
  • 因為狀態轉移只依賴于上一行的狀態,所以可以用一維數組代替二維數組。
2. 從右到左更新
  • 在更新 f[j] 時,f[j - v[i]] 表示未選擇當前物品時的狀態。
  • 如果從左到右更新(如 for (int j = v[i]; j <= m; j++)),會導致 f[j - v[i]] 被當前物品更新過,從而出現重復選擇當前物品的情況。
  • 因此,必須從右到左更新(如 for (int j = m; j >= v[i]; j--)),確保每個物品只被選擇一次。
3. 狀態轉移方程
  • 狀態轉移方程保持不變:
    f [ j ] = max ? ( f [ j ] , f [ j ? v [ i ] ] + w [ i ] ) f[j] = \max(f[j], f[j - v[i]] + w[i]) f[j]=max(f[j],f[j?v[i]]+w[i])
    • f[j] 表示不選擇當前物品時的最大價值。
    • f[j - v[i]] + w[i] 表示選擇當前物品時的最大價值。
4. 初始化
  • 初始化 f 數組為 0,表示在沒有物品時,所有背包容量的最大價值都為 0。
5. 輸出結果
  • 最終結果存儲在 f[m] 中,表示背包容量為 m 時的最大價值。

復雜度分析

時間復雜度
  • 外層循環遍歷物品數量 n n n,內層循環遍歷背包容量 m m m
  • 時間復雜度為 O ( n × m ) O(n \times m) O(n×m)
空間復雜度
  • 使用了一維數組 f,空間復雜度為 O ( m ) O(m) O(m)

注意事項

  1. 從右到左更新的重要性

    • 如果改為從左到右更新(如 for (int j = v[i]; j <= m; j++)),會導致每個物品被多次選擇,變成 完全背包問題 的解法。
    • 因此,在 0-1 背包問題 中,必須從右到左更新。
  2. 適用場景

    • 這段代碼適用于 0-1 背包問題,即每個物品只能選擇一次。
    • 如果是 完全背包問題(每個物品可以無限次選擇),需要將狀態轉移方程改為 f[j] = max(f[j], f[j - v[i]] + w[i]),并且內層循環改為從左到右更新。

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

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

相關文章

深入理解Java享元模式及其線程安全實踐

引言 在軟件系統中&#xff0c;當需要處理海量細粒度對象時&#xff0c;直接創建大量實例可能會導致內存消耗激增和性能下降。享元模式&#xff08;Flyweight Pattern&#xff09;通過共享對象內部狀態&#xff0c;成為解決這類問題的經典方案。然而在多線程環境下&#xff0c…

1、mysql基礎篇--概述

關系型數據庫&#xff08;RDBMS&#xff09; 概念特點&#xff1a;數據模型&#xff1a; 概念 建立在關系模型基礎上&#xff0c;有多張表相互連接的二維表組成的數據庫 特點&#xff1a; 1、使用表存儲&#xff0c;格式統一&#xff0c;便于維護 2、使用sql語言操作&#…

如何提升庫存系統的高并發和穩定性:算法與設計模式

庫存系統是企業運營的核心模塊&#xff0c;尤其是在電商、零售和供應鏈管理中&#xff0c;系統的高并發和穩定性直接影響訂單處理的準確性和效率。面對海量訂單、復雜的庫存管理需求&#xff0c;如何在高并發環境下確保庫存數據的準確性和系統的穩定性&#xff1f;本文將從架構…

【多線程】synchronized底層實現的方式

前言 在java 開發中對于鎖的應用非常的常見&#xff0c;如果對于什么時候該用什么鎖&#xff0c;以及鎖實現的原理有所不知道的&#xff0c;或者面試過程中面試官問你不知道怎么回答的&#xff0c;歡迎來看下面的文章 1、synchronized和ReentrantLock的區別 2、synchronized的…

Pytorch中Tensorboard的學習

1、Tensorboard介紹 TensorBoard 是 TensorFlow 開發的一個可視化工具&#xff0c;用于幫助用戶理解和調試機器學習模型的訓練過程。盡管它最初是為 TensorFlow 設計的&#xff0c;但通過 PyTorch 的 torch.utils.tensorboard 模塊&#xff0c;PyTorch 用戶也可以方便地使用 Te…

ETL 自動化:提升數據處理效率與準確性的核心驅動力

在數字化轉型的浪潮中&#xff0c;數據已成為企業戰略資產&#xff0c;高效處理數據的能力直接關系到企業的競爭力。ETL&#xff08;Extract, Transform, Load&#xff09;自動化作為數據處理領域的關鍵技術&#xff0c;正逐漸成為企業在數據時代脫穎而出、實現高效運營與精準決…

std::endl為什么C++ 智能提示是函數?

在使用vscode 的C智能提示后&#xff0c;輸入endl 后&#xff0c;提示的卻是std::endl(basic_ostream<CharT, Traits> &os), 感覺比較奇怪&#xff0c;各種代碼里都是直接用的std::endl 啊&#xff0c; 這里怎么變成函數了呢&#xff1f; 在 C 中&#xff0c;std::en…

簡潔、實用、無插件和更安全為特點的WordPress主題

簡站WordPress主題是一款以簡潔、實用、無插件和更安全為特點的WordPress主題&#xff0c;自2013年創立以來&#xff0c;憑借其設計理念和功能優勢&#xff0c;深受用戶喜愛。以下是對簡站WordPress主題的詳細介紹&#xff1a; 1. 設計理念 簡站WordPress主題的核心理念是“崇…

數據結構篇:空間復雜度和時間復雜度

目錄 1.前言&#xff1a; 1.1 學習感悟 1.2 數據結構的學習之路(初階) 2.什么是數據結構和算法 2.1 數據結構和算法的關系 2.2 算法的重要性 2.3 如何衡量算法的好壞 3.時間復雜度 3.1 時間復雜度的概念 3.2 大O的漸進表示法 O() 4.空間復雜度 5. 常見的時間復雜度和…

node-ddk,electron,截屏封裝(js-web-screen-shot)

node-ddk 截屏封裝(js-web-screen-shot) https://blog.csdn.net/eli960/article/details/146207062 也可以下載demo直接演示 http://linuxmail.cn/go#node-ddk 感謝/第三方 本截屏工具, 使用的是: js-web-screen-shot https://www.npmjs.com/package/vue-web-screen-shot…

泰坦軍團攜手順網旗下電競連鎖品牌樹呆熊 共創電競新紀元

在電競行業的浪潮中&#xff0c;品牌之間的戰略合作愈發成為推動市場前行的重要動力。最近&#xff0c;電競顯示器領域領軍品牌泰坦軍團高層領導出席順網旗下電競連鎖品牌樹呆熊十周年盛典。會議現場&#xff0c;雙方高層領導宣布泰坦軍團與樹呆熊正式達成戰略合作伙伴關系。 在…

HandyJSON原理

HandyJSON 的優勢 JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式, 應用廣泛. 在 App 的使用過程中, 服務端給移動端發送的大部分都是 JSON 數據, 移動端需要解析數據才能做進一步的處理. 在解析JSON數據這一塊, 目前 Swift 中流行的框架基本上是 SwiftyJSON, …

信號的產生和保存

信號的產生 信號就是操作系統對用戶操作做出的反應&#xff0c;但它的本質就是往操作系統寫入信號&#xff0c;這是由操作系統的結構決定的。通過修改比特位來告訴操作系統接收信號和傳了幾號信號。 也正是因為我們身為用戶無法親自修改內核數據&#xff0c;所以我們需要通過操…

在C++ Qt中集成Halcon窗口并實現跨平臺兼容和大圖加載

目錄 1. Halcon窗口嵌入Qt Widget 2. 處理大圖加載 3. 多線程優化顯示 4. 跨平臺兼容性 1. Halcon窗口嵌入Qt Widget 將Halcon的HWindow控件嵌入到Qt的QWidget容器中,利用系統原生句柄實現跨平臺。 #include <HalconCpp.h> #include <QWidget>class HalconWi…

深度學習技術與應用的未來展望:從基礎理論到實際實現

深度學習作為人工智能領域的核心技術之一&#xff0c;近年來引起了極大的關注。它不僅在學術界帶來了革命性的進展&#xff0c;也在工業界展現出了廣泛的應用前景。從圖像識別到自然語言處理&#xff0c;再到強化學習和生成對抗網絡&#xff08;GAN&#xff09;&#xff0c;深度…

藍光三維掃描技術:汽車零部件檢測的精準高效之選

——汽車方向盤配件、保險杠塑料件、鈑金件檢測項目 汽車制造工業的蓬勃發展&#xff0c;離不開強大的零部件制造體系作支撐。汽車零部件作為汽車工業的基礎&#xff0c;其設計水平、制造工藝、質量控制手段逐漸與國際標準接軌&#xff0c;對于零部件面差、孔位、圓角、特征線…

數據庫聯表Sql語句建一個新表(MySQL,Postgresql,SQL server)

數據庫聯表Sql語句建一個新表(MySQL,Postgresql,SQL server) 如果你想基于 SELECT USERS.ID,USERS.NAME,USERS.EMAIL,USERS.ID_CARD,USERS.V_CARD,USERS.ADDRESS,v_card.type,v_card.amount FROM USERS JOIN v_card on USERS.V_CARDv_card.v_card 這個查詢結果創建一個新表&am…

六十天前端強化訓練之第三十天之深入解析Vue3電商項目:TechStore全棧實踐(文結尾附有源代碼)

歡迎來到編程星辰海的博客講解 看完可以給一個免費的三連嗎&#xff0c;謝謝大佬&#xff01; 目錄 深入解析Vue3電商項目&#xff1a;TechStore全棧實踐 一、項目架構設計 二、核心功能實現 三、組合式API深度實踐 四、性能優化實踐 五、項目擴展方向 六、開發經驗總結…

【人工智能】機器學習中的評價指標

機器學習中的評價指標 在機器學習中&#xff0c;評估指標&#xff08;Evaluation Metrics&#xff09;是衡量模型性能的工具。選擇合適的評估指標能夠幫助我們更好地理解模型的效果以及它在實際應用中的表現。 一般來說&#xff0c;評估指標主要分為三大類&#xff1a;分類、…

不同機床對螺桿支撐座的要求有哪些不同?

螺桿支撐座是機械設備中重要的支撐部件&#xff0c;其選擇直接影響到設備的穩定性和使用壽命&#xff0c;尤其是在機床中&#xff0c;不同的機床對螺桿支撐座的要求也是不同的。 1、精度&#xff1a;精密測量用的基準平面和精密機床機械的檢驗測量設備&#xff0c;需要使用高精…