經典01揹包問題

2021-10-09 22:57:26 字數 1993 閱讀 2148

乙個旅行者有乙個最多能裝m公斤的揹包,現在有n件物品,它們的重量分別是w1,w2,…,wn,它們的價值分別為c1, c2, …,cn。 求旅行者能獲得最大總價值。

第 1 行:兩個整數,m(揹包容量,m<=200)和n(物品數量,n <=30);

第 2 到 n+1行: 每行兩個整數 wi,ci,表示每個物品的重量和價值。

10 4

2 13 3

4 57 9

12

01揹包問題特點:

每種物品僅有一件,可以選擇放或不放。

說明:不放分為被動不放和主動不去放當前物品兩種情況

定義狀態

f[i][v]表示前i件物品(全部或部分)放入乙個容量為v(0<=v<=m)的揹包可以獲得的最大價值。

當前物品 i 有兩種可能性:

包的容量(需依次列舉1<=v<=m中的每個包容量狀態)比當前物品容量小,裝不下,此時的最優價值與前i-1個的最優價值是一樣的,即 f[i][v] = f[i-1][v]

包的容量大於等於當前物品容量,可以選擇向包裡放入該物品,但未必能得到當前最優的價值f[i][v]。所以在放與不放該物品兩者之間選擇最優的一種策略。此時的不放為主動不放,前一種可能性裡的放不下屬於被動不放

即:f[i][v]=max

綜合分析 ,得到如下狀態轉移方程:

if(w[i] < =v) f[i][v] = max(f[i-1][v],f[i-1][v-w[i]]+c[i]]);?

else f[i][v] =f[i-1][v];

// c++**

#include#includeusing namespace std;

/*部分揹包問題屬於貪心

經典01揹包問題多歸於動態規劃演算法範疇

*/ const int maxm=201, maxn=31;

int m,n;

int w[maxn],c[maxn];//w 重量,c 價值

int f[maxn][maxm];//dp[maxn][maxm]

int main()

cout<< f[n][m]<#include

#include

using

namespace std;

/*部分揹包問題屬於貪心

經典01揹包問題多歸於動態規劃演算法範疇

*/const

int maxm=

201, maxn=31;

int m,n;

int w[maxn]

,c[maxn]

;//w 重量,c 價值

int dp[maxm]

;//dp[v]表示重量不超過v公斤的最大價值

//如有n個物品,可分n個階段,用迴圈

// 第i個階段某個v狀態,是從第i-1個階段v狀態轉移過來的

//如價值大於前一階段的狀態,則更新當前狀態 ,否則不更新

intmain()

cout<< dp[m]

return0;

}

初始化邊界:dp[0][v] =dp[i][0]=0

dp[n][m] 即為旅行者揹包能獲得的最大總價值。

i/v01

2345

6789

10000

0000

0000

0100

1111

1111

1200

1334

4444

4300

1355

6889

9400

1355

6889

12

經典問題之01揹包

動態規劃像乙個生產車間有好多連續的生產線 乙個階段就是乙個生產線 狀態就是每個生產線物品的狀態 決策就是生產線上根據物品的狀態而對物品的操作.01揹包問題 階段 第一生產線 放不放第乙個物品 第二生產線 放不放第二個物品 第n生產線 放不放第n個物品 第一生產線共 有n v1個選擇 v v時放不放 ...

經典演算法問題 0 1 揹包

一 問題描述 有n 個物品,它們有各自的重量和價值,現有給定容量的揹包,如何讓揹包裡裝入的物品具有最大的價值總和?二 問題分析 1 用v i 表示物品價值,w i 表示物品重量。定義狀態dp i j 以j為容量為放入前i個物品 按i從小到大的順序 的最大價值。2 初始化邊界條件,v 0,j v i,...

經典揹包問題 01揹包 完全揹包 多重揹包

1 for int i 0 i 2for int j w j size i j 3 f j max f j f j size i value i 1 for int i 0 i 2for int j size i j w j 3 f j max f j f j size i value i f w ...