簡單揹包問題

2021-10-01 05:59:51 字數 1506 閱讀 7922

有乙個容量為v的揹包,從n件物品中選擇一些放入揹包中,每件物品的重量為w[i],**為v[i].怎麼選擇合適的物品使得揹包內物品的總價值最大.

這個問題中每個物品可供選擇的次數是0或1.即簡單揹包問題.

若可選擇次數為n(n為乙個有效的數字),則稱之為有界揹包問題.

若可選擇次數無限,則稱之為無界揹包問題.

所有的揹包問題都可以變換為簡單揹包問題.

在本題中,如果我們假設f[i][v]表示第i件物品放入揹包後的最大總價值,那麼有:

f[i][v] = max(f[i-1][v],f[i-1][v-w[i]]+v[i]);

第i件物品只有兩種選擇,放入或者不放入揹包,如果不能放入揹包,那麼前i件物品的總價值就是前i-1件物品的總價值,等於f[i-1][v],而假設第i件物品放入了揹包之中,前i件物品的總價值則為f[i-1][v-w[i]]+v[i]. v-w[i]即是前i-1件物品的重量.

該狀態轉移方程可壓縮空間至:f[v] = max(f[v],f[v-w[i]]+v[i]).

所以該問題的解法可以看成,在1~n的外迴圈之中求所有f[0~v]的值,而所有f[v]的都依賴上一次主迴圈的當前值即f[v]和小於當前值的f[v-w[i]]+v[i].所以內迴圈採用逆序遍歷,因為順序遍歷的話,f[v]的值已經改變,f[v+w[k]]的值如果依賴了f[v],那麼f[v+w[k]]的值會出錯.偽**如下

for i = 1......n

for v = v......0

f[v] = max(f[v],f[v-w[i]]+v[i])

給定乙個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。

注意:每個陣列中的元素不會超過 100

陣列的大小不會超過 200

示例 1:

輸入: [1, 5, 11, 5]

輸出: true

解釋: 陣列可以分割成 [1, 5, 5] 和 [11].

示例 2:

輸入: [1, 2, 3, 5]

輸出: false

解釋: 陣列不能分割成兩個元素和相等的子集.

分析題目可知,將整個陣列劃分為兩組,每組和等於 sum(nums)/2,而陣列內的元素只能選擇一次,類似於0,1揹包問題. sum(nums)/2為揹包容量v,nums[i]可看做物品的重量w[i].

**如下:

public boolean canpartition(int nums) 

if ((s & 1) == 1)

int target = s / 2;

boolean dp = new boolean[target + 1];

// 先寫第 1 行,看看第 1 個數是不是能夠剛好填滿容量為 target

for (int j = 1; j < target + 1; j++)

}for (int i = 1; i < size; i++)

}return dp[target];

}

**參考了題解:

簡單揹包問題

設有乙個揹包可以放入的物品重量為s,現有n件物品,重量分別是w1,w2,w3,wn。問能否從這n件物品中選擇若干件放入揹包中,使得放入的重量之和正好為s。如果有滿足條件的選擇,則此揹包有解,否則此揹包問題無解。input 輸入資料有多行,包括放入的物品重量為s,物品的件數n,以及每件物品的重量 輸入...

簡單揹包問題

設有乙個揹包可以放入的物品重量為s,現有n件物品,重量分別是w1,w2,w3,wn。問能否從這n件物品中選擇若干件放入揹包中,使得放入的重量之和正好為s。如果有滿足條件的選擇,則此揹包有解,否則此揹包問題無解。輸入輸入資料有多行,包括放入的物品重量為s,物品的件數n,以及每件物品的重量 輸入資料均為...

簡單0 1揹包問題

有乙個揹包能裝的重量maxw 正整數,0 maxw 20000 同時有n件物品 0 n 100 每件物品有乙個重量wi 正整數 和乙個價值pi 正整數 要求從這n件物品中任取若干件裝入揹包內,使揹包的物品價值最大。第1行 揹包最大載重maxv,物品總數n 第2行到第n 1行 每個物品的重量和價值 乙...