藍橋杯C++基礎算法-多重背包(優化)

這段代碼實現了一個多重背包問題的動態規劃解法,并且使用了二進制拆分(或稱二進制優化)來優化物品的數量處理。這種方法可以顯著減少狀態轉移的次數,提高算法的效率。以下是代碼的詳細思路解析:


1. 問題背景

給定 n 個物品,每個物品有其體積 a、價值 b 和數量 s,以及一個容量為 m 的背包。目標是選擇物品使得總價值最大,同時總容量不超過背包的容量。與完全背包問題不同的是,多重背包問題中每個物品的數量是有限的。

2. 二進制拆分的概念

二進制拆分是一種優化技巧,用于處理多重背包問題中的物品數量。通過將每個物品的數量 s 拆分成若干個部分,每個部分的數量為 2^kk 從 0 開始),可以顯著減少狀態轉移的次數。例如,如果 s = 13,可以拆分成 1 + 2 + 4 + 6,其中 1 + 2 + 4 = 7,剩余的 6 作為最后一部分。

3. 代碼邏輯解析

(1) 輸入數據
cin >> n >> m;
int cnt = 0;
for (int i = 1; i <= n; i++)
{int a, b, s;cin >> a >> b >> s;int k = 1;while (k <= s){cnt++;v[cnt] = a * k;w[cnt] = b * k;s -= k;k *= 2;}if (s > 0){cnt++;v[cnt] = a * s;w[cnt] = b * s;}
}
n = cnt;
  • 用戶輸入物品數量 n 和背包容量 m

  • 對于每個物品,輸入其體積 a、價值 b 和數量 s

  • 使用二進制拆分將每個物品的數量 s 拆分成若干個部分,每個部分的數量為 2^k

  • 將每個部分作為一個新的物品,存儲到數組 vw 中。

  • 更新物品總數 n 為拆分后的物品數量 cnt

(2) 動態規劃狀態轉移
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]);
  1. 外層循環

    • 遍歷每個物品,從第 1 個到第 n 個。

  2. 內層循環

    • 遍歷背包的每個容量,從 mv[i](逆序遍歷)。

    • 逆序遍歷的原因是避免重復使用同一個物品。如果正序遍歷,同一個物品可能會被多次使用,從而變成完全背包問題。

  3. 狀態轉移

    • f[j] 表示在容量為 j 的背包下的最大價值。

    • 不選擇第 i 個物品f[j] 保持不變。

    • 選擇第 i 個物品:如果當前容量 j 大于等于第 i 個物品的體積 v[i],則可以考慮選擇第 i 個物品,更新 f[j]f[j - v[i]] + w[i],即在容量為 j - v[i] 的背包下的最大價值加上第 i 個物品的價值。

(3) 輸出結果
cout << f[m] << endl;
  • 輸出最終的最大價值,即 f[m]

4. 代碼效率分析

  • 時間復雜度

    • 二進制拆分將每個物品的數量 s 拆分成若干個部分,每個部分的數量為 2^k,因此每個物品最多被拆分成 O(log s) 個部分。

    • 動態規劃的狀態轉移時間復雜度為 O(n × m),其中 n 是拆分后的物品數量。

    • 總時間復雜度為 O(n × m × log s)

  • 空間復雜度

    • 使用了一個一維數組 f,空間復雜度為 O(m)

5. 示例運行

輸入:
4 5
1 2 3
2 4 1
3 4 3
4 5 2
輸出:
10

6. 總結

這段代碼的核心思路是通過動態規劃解決多重背包問題,并使用二進制拆分優化物品的數量處理。通過維護一個一維數組 f,記錄不同狀態下的最大價值,并通過狀態轉移方程更新最大價值,最終找到在給定背包容量下的最大價值。這種方法的時間復雜度為 O(n × m × log s),空間復雜度為 O(m),適用于中等規模的多重背包問題。

完整代碼

#include<bits/stdc++.h>
using namespace std;// 定義常量 N 和 M,N 用于數組大小,M 這里未使用
const int N = 25000, M = 2010;
// n 表示物品的種類數,m 表示背包的容量
int n, m;
// v 數組存儲物品的體積,w 數組存儲物品的價值
int v[N], w[N];
// f 數組是一維數組,f[j] 表示背包容量為 j 時能獲得的最大價值
int f[N];int main()
{// 輸入物品的種類數 n 和背包的容量 mcin >> n >> m;// cnt 用于記錄經過二進制優化后物品的數量int cnt = 0;// 循環處理每種物品for(int i = 1; i <= n; i ++){// 輸入當前物品的體積 a、價值 b 和數量上限 sint a, b, s;cin >> a >> b >> s;// k 用于二進制拆分,初始為 1int k = 1;// 進行二進制拆分while(k <= s){// 物品數量加 1cnt ++;// 計算拆分后物品的體積v[cnt] = a * k;// 計算拆分后物品的價值w[cnt] = b * k;// 減去已拆分的數量s -= k;// k 乘以 2,繼續下一次拆分k *= 2;}// 如果還有剩余數量,將剩余部分作為一個新物品if(s > 0){cnt ++;v[cnt] = a * s;w[cnt] = b * s;}}// 更新物品的種類數為拆分后的數量n = cnt;// 使用 0 - 1 背包的方法進行動態規劃for(int i = 1; i <= n; i ++)// 內層循環從背包的最大容量 m 開始,遞減到當前物品的體積 v[i]for(int j = m; j >= v[i]; j --)// 比較不選擇第 i 個物品和選擇第 i 個物品兩種情況下的最大價值f[j] = max(f[j], f[j - v[i]] + w[i]);// 輸出背包容量為 m 時能獲得的最大價值cout << f[m] << endl;return 0;
}

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

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

相關文章

FALL靶機攻略

1.下載靶機&#xff0c;導入靶機 下載地址&#xff1a;https://download.vulnhub.com/digitalworld/FALL.7z 開啟靶機。 2. 靶機、kali設置NAT網卡模式 3. kali掃描NAT網卡段的主機 kali主機 nmap掃描&#xff1a;nmap 192.168.92.1/24 判斷出靶機ip是192.168.92.133。開啟…

notepad++代碼查看器分享

文章目錄 &#x1f4dd; Notepad 簡介&#x1f527; 主要特點打開.c文件示意高亮語法展示全局替換功能展示 &#x1f4dd; Notepad 簡介 Notepad 是一款 免費的開源文本編輯器和源代碼編輯器&#xff0c;運行在 Windows 系統上。 它是對 Windows 自帶“記事本”的增強版本&…

詳細介紹Spring MVC的執行流程是怎么樣的?

Spring MVC 是 Spring 框架的一部分&#xff0c;用于構建 Web 應用程序。它的執行流程如下&#xff1a; 前端控制器&#xff08;DispatcherServlet&#xff09;接收請求&#xff1a;用戶通過瀏覽器發送 HTTP 請求到服務器&#xff0c;請求首先被前端控制器 DispatcherServlet 接…

MySQL中的內連接與外連接詳解:基礎與進階應用

文章目錄 表的內連和外連&#xff08;重點&#xff09;內連接外連接左外連接右外連接 簡單回顧 表的內連和外連&#xff08;重點&#xff09; 表的連接分為內連和外連 內連接 內連接實際上就是利用where子句對兩種表形成的笛卡兒積進行篩選&#xff0c;我們前面學習的查詢都…

動態內存分配與內存對齊

在C語言及其他低級編程語言中,內存管理是一個至關重要的主題。動態內存分配和內存對齊是確保程序高效和穩定運行的關鍵因素。本文將深入探討動態內存分配的原理,內存對齊的概念,并解釋它們如何共同影響程序的性能和資源利用。 一、動態內存分配簡介 1.1 動態內存分配的概念…

Milvus×最新版DeepSeek v3:對標Claude,本地數據五分鐘寫網站

前言 就在昨晚&#xff0c;DeepSeek v3推出了新版本V3-0324&#xff0c;再次一夜爆火。 雖然官方表示“這只是一次小升級”“API接口和使用方式不變”&#xff0c;但經過Zilliz的第一時間實測&#xff0c;我們發現無論是邏輯能力&#xff0c;還是編程能力&#xff0c;相較原本的…

6.M-LAG專題

M-LAG 的作用及特點 能不能簡單的描述以下M-LAG的工作原理? 跨設備鏈路聚合&#xff0c;將兩臺物理設備在聚合層面虛擬成一臺設備來實現跨設備鏈路聚合&#xff0c;從而提供設備級冗余保護和流量負載分擔 M-LAG(跨設備鏈路聚合)是基于IEEEP802.1A協議的跨設備鏈路聚合技術。…

每日免費分享之精品wordpress主題系列~DAY16

主題介紹&#xff1a; 今日在網上尋找wordpress主題的時候逛到了大叔的網站&#xff0c;趕腳這個主題蠻不錯的&#xff0c;于是百度一下&#xff0c;果然&#xff0c;這個主題很受歡迎。作為主題下載站追夢者也不甘落后&#xff0c;馬上就發布出來了&#xff0c;希望對你們有用…

LeeCode 383. 贖金信

給你兩個字符串&#xff1a;ransomNote 和 magazine &#xff0c;判斷 ransomNote 能不能由 magazine 里面的字符構成。 如果可以&#xff0c;返回 true &#xff1b;否則返回 false 。 magazine 中的每個字符只能在 ransomNote 中使用一次。 示例 1&#xff1a; 輸入&#…

目標檢測20年(一)

今天看的文獻是《Object Detection in 20 Years: A Survey》&#xff0c;非常經典的一篇目標檢測文獻&#xff0c;希望通過這篇文章學習到目標檢測的基礎方法并提供一些創新思想。 論文鏈接&#xff1a;1905.05055 目錄 一、摘要 1.1 原文 1.2 翻譯 二、介紹 三、目標檢測…

分割 / 合并大文件的簡單 python 代碼

使用方法 分割: python fs.py -n <分割后的文件個數> <要分割的文件> 合并: python fs.py -m <分割文件1> <分割文件2> ... 示例 PS C:\Users\Administrator\Desktop> python fs.py 使用方法: 分割: python fs.py -n <分割后的文件個數> &…

IDEA 快捷鍵ctrl+shift+f 無法全局搜索內容的問題及解決辦法

本篇文章主要講解IDEA、phpStrom、webStrom、pyCharm等jetbrains系列編輯器無法進行全局搜索內容問題的主要原因及解決辦法。 日期&#xff1a;2025年3月22日 作者&#xff1a;任聰聰 現象描述&#xff1a; 1.按下ctrlshiftf 輸入法轉為了繁體。 2.快捷鍵ctrlshiftr 可以全局檢…

樹狀數組【數據結構】

樹狀數組 簡介 1.應用 1.單點修改區間查詢 2.區間修改單點查詢(差分) 3.區間修改區間查詢(差分公式) 總而言之,就是動態維護前綴和。 2.樹狀結構圖 3.lowbit函數 我們知道&#xff0c;任何一個正整數都可以被表示成一個二進制數。如&#xff1a; ( 2 ) 10 ( 10 ) 2 (2)_{10…

pytorch+maskRcnn框架訓練自己的模型以及模型導出ONXX格式供C++部署推理

背景 maskrcnn用作實例分割時&#xff0c;可以較為精準的定位目標物體&#xff0c;相較于yolo只能定位物體的矩形框而言&#xff0c;優勢更大。雖然yolo的計算速度更快。 直接開始從0到1使用maskrCNN訓練自己的模型并并導出給C部署&#xff08;親測可用&#xff09; 數據標注…

PCL配置

1、下載 打開GitHub網站&#xff0c;搜索pcl&#xff0c;選擇第一個結果打開&#xff0c;按照下圖步驟操作 下載PCL預編譯安裝程序PCL-1.13.1-AllInOne-msvc2022-win64.exe 和要安裝的PCL組件&#xff08;例如pcl-1.13.1-pdb-msvc2022-win64.zip&#xff09; 2、安裝 雙擊 P…

大模型tokenizer重構流程

大模型tokenizer層再訓練&#xff08;選取Qwen7B試驗&#xff0c;重構token層&#xff09; 最近公司可能想訓練一個蛋白質大模型&#xff0c;需要了解一下大模型tokenizer重構&#xff0c;之后可能要訓練&#xff0c;這里做了一定的總結。 文章目錄 1. 首先查看Qwen2.5 7B基本…

Android設計模式之單例模式

一、定義&#xff1a;確保一個類只有一個實例&#xff0c;并且自動實例化&#xff0c;并向整個系統提供這個實例。 二、使用場景&#xff1a;避免重復創建對象&#xff0c;過多消耗系統資源。 三、使用方式 3.1餓漢式&#xff1a;類加載時立即初始化&#xff0c;線程安全&…

docker ssh遠程連接

目錄 操作命令&#xff1a; 確保 SSH 配置允許 root 登錄&#xff1a; docker提交&#xff1a; 操作命令&#xff1a; # 進入容器 docker exec -ti lbg04 /bin/bash# 更新包管理并安裝 SSH 服務&#xff08;Ubuntu/Debian 示例&#xff09; apt-get update apt-get install…

關于matlab和python誰快的問題

關于matlab和python誰快的問題&#xff0c;python比matlab在乘法上快10倍&#xff0c;指數計算快4倍&#xff0c;加減運算持平&#xff0c;略慢于matlab。或許matlab只適合求解特征值。 import torch import timen 50000 # 矩陣規模 M torch.rand(n, 31)start_time time.t…

準確--配置服務器文件數

某些系統可能在 /etc/security/limits.d/ 目錄下有額外配置覆蓋全局設置。檢查是否存在沖突文件&#xff1a; ls /etc/security/limits.d/如果有文件&#xff08;如 90-nproc.conf 或 90-nofile.conf&#xff09;&#xff0c;需編輯或刪除這些文件中的沖突配置。 確保系統啟用…