有乙個容量為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行 每個物品的重量和價值 乙...