原部落格:0-1揹包問題
描述:
乙個揹包容量為c ,現有n件物品,求能裝入揹包的最大重量是多少?
輸入:
先輸入兩個正整數n、c(0輸出:
輸出能裝入揹包的最大重量。
輸入樣例:
5 5023 18 13 35 24
輸出樣例:
48
方法一:
0-1揹包的裸題,那就可以直接寫乙個01揹包的動態轉移方程:dp[j]=max(dp[j],dp[j-w[i]]+p[i])。dp[j]的意思是:當揹包已裝j的重量的物品時的最大價值。那麼它可以由揹包已裝j-w[i]時最大的價值進行轉移,即由dp[j-w[i]]+p[i]得到。注意每一次要將dp設定為0,因為揹包此時無價值。當狀態方程列舉結束後,我們再從 dp陣列中找一遍,求得答案maxx=max(i from 0 to c),輸出答案maxx。這種動態規劃的方法的時間複雜度為o(n^2).
ps:0-1揹包也可以寫成二維dp,只是這樣寫成滾動陣列可以更加節省空間。
方法二:
除了直接寫0-1揹包的動態轉移方程,還可以直接寫dfs,每乙個揹包無非就是取和不取兩個狀態,如果要取則要求揹包容量 res>=w[now]。分別用ans1,ans2表示取當前物品,不取當前物品的最大價值,dfs返回max(ans1,ans2),dfs的終止條件是now ==n+1。時間複雜度(2^n)。
ps:方法二相較於方法一思維上更加簡單,容易想到,但是**就相對麻煩,並且時間複雜度不夠優秀,當然如果加上記憶化搜尋後時間複雜度和動態規劃是相當的。我個人更喜歡方法一。
#include
#include
#include
#include
using
namespace std;
const
int maxn=
2000+50
;int n,c,w[maxn]
,dp[maxn]
,p[maxn]
;int
main()
}}int maxx=0;
for(i=
0;i<=c;i++)if
(maxx) maxx=dp[i]
; cout
}
#include
#include
#include
#include
using
namespace std;
const
int maxn=
2000+50
;int n,c,w[maxn]
,p[maxn]
;int
dfs(
int now,
int res)
ans2=
dfs(now+
1,res);if
(ans1>=ans2)
return ans1;
return ans2;
}int
main()
NOJ 1004 0 1揹包問題
時限 1000ms 記憶體限制 10000k 總時限 3000ms 描述需對容量為c 的揹包進行裝載。從n 個物品中選取裝入揹包的物品,每件物品i 的重量為wi 價值為pi 對於可行的揹包裝載,揹包中物品的總重量不能超過揹包的容量,最佳裝載是指所裝入的物品價值最高。輸入多個測例,每個測例的輸入佔三行...
noj 1004 0 1揹包問題 dfs
時限 1000ms 記憶體限制 10000k 總時限 3000ms 描述 需對容量為c 的揹包進行裝載。從n 個物品中選取裝入揹包的物品,每件物品i 的重量為wi 價值為pi 對於可行的揹包裝載,揹包中物品的總重量不能超過揹包的容量,最佳裝載是指所裝入的物品價值最高。輸入 多個測例,每個測例的輸入佔...
揹包問題 01揹包問題
n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...