老師好,我是刁同學!
關於如何理解這個問題,我看了很多其他博主寫的部落格,但是大多數關於窮舉法的(在我看來比較麻煩,思路上不太清晰),從問題的本源來說,這就是乙個關於選擇的問題。就像是傳送帶上的物品,而你只有乙個有限的揹包,對於你來說只是要不要眼前的序號為i的物品,從你開始選擇開始,如果沒有揹包限額的規定,直到最後乙個物品t的選擇截止,你一共只有2^t種不同的選擇(對每個單獨的物品來說只有選或者不選)。明明晃晃的二叉樹結構,而這種結構,被二進位制的01字串演繹的淋漓盡致,我們甚至都不需要做其他的改動。把十進位制轉化成二進位制,就是我們所有的選擇了。0代表不選,1代表選。在面對有限空間時,我們就要考慮每次選擇之後的剩餘空間了,這也不是太難的問題,只需簡單統計即可。在每種選擇背後,如果揹包在你還沒選完時就已經滿了,就不需考慮這種取法了。在所有選擇中一定有比他更合適的。最後,只需在符合條件的情況下,選擇價值最大就行了,而他就是你要的答案。
import mathn=[
]#確定組合數v=[
]#記錄每件物品的價值m=[
]#記錄每件物品重量c=[
]#記錄總價w=[
]#記錄總重量
max=
0#記錄最大取值
num=
0#最大取值時的取法
t=int
(input
("請輸入問題規模:"))
b=int
(input
("輸入揹包的最大容量:"))
for i in
range(0
,t):
int(
input
("請輸入第%d件物品的價值:"
%i))
)int
(input
("請輸入第%d件物品的重量:"
%i))
)for i in
range(0
,int
(math.
pow(
2,t)))
:int(''
.format
(i)))0
)0)for i in
range(1
,int
(math.
pow(
2,t)))
: flag=
true
q=0while flag:
if(n[i]/10
>=1)
: w[i]
+=(n[i]%10
)*m[q]
if(w[i]
>b)
:break
else
: c[i]
+=(n[i]%10
)*v[q]
n[i]
=n[i]
//10
q+=1elif
(n[i]==1
):w[i]
+=(n[i]%10
)*m[q]
if(w[i]
>b)
:break
else
: c[i]
+=(n[i]%10
)*v[q]
n[i]
=n[i]
//10
q+=1 flag=
false
for i in
range(1
,int
(math.
pow(
2,t)))
:if(c[i]
>
max)
:max
=c[i]
num=i
print
("最大的價值是:%d"
%max
)print
("取法是(對應關係為最低位開始對應第0個物品.1為取.0為不取):''"
.format
(num)
)
請輸入問題規模:5
輸入揹包的最大容量:20
請輸入第0件物品的價值:3
請輸入第0件物品的重量:2
請輸入第1件物品的價值:4
請輸入第1件物品的重量:3
請輸入第2件物品的價值:5
請輸入第2件物品的重量:4
請輸入第3件物品的價值:8
請輸入第3件物品的重量:5
請輸入第4件物品的價值:10
請輸入第4件物品的重量:9
最大的價值是:26
取法是(對應關係為最低位開始對應第0個物品.1為取.0為不取):『11101』
ps:(結果解釋)即取第4、3、2號物品;不取1號;取0號物品。
窮舉法求解24點
看到網上更多的是推薦使用遞迴,但是自己對遞迴一向有點頭疼,所有使用窮舉法求解。vs2005下測試通過。1 2使用窮舉法求解24點。3但是仍然有乙個問題 對於1 2與2 1,因為順序的關係,4系統仍然認為其是兩個解,此問題尚待解決。5author chris 6date 2013 06 18 7 8 ...
暴力法求解01揹包問題
這段 只是使用暴力法解決了01揹包問題,但是沒有經過優化,效率不高。使用暴力法的原因只是因為作業需求,請勿評價。主要的難點在於使用c語言列出乙個陣列的所有子集。使用了遞迴的方法,將每次的計算都歸併為二個元素,這樣就能夠簡化問題。main.c backpack created by shadowdai...
回溯法求解01揹包問題
在前面文章我們使用動態規劃求解了揹包問題,時間複雜度是o cn 當我們的c的值非常大的時候,說消耗的時間也是非常大的!接下來我們就使用回溯法來求解這個問題,其時間複雜度為o n2n 這個結果當我們的c的值是小於2n 的時候,該演算法所需的時間是小於動態規劃的!既然使用了回溯法,我們就的構造解析樹,因...