01揹包詳解
阿新 • • 發佈:2018-12-19
01揹包 給定一個容量為c的揹包,有n個物品,第i個質量為wi,價值為vi,求揹包的最大價值
由於每種物品只有1個,因此每個物品只有01兩種狀態,即拿和不拿 用V【i,j】表示在面對第i個物品且揹包容量為j時,揹包內的最大價值
那麼顯然,V【0,j】和V【i,0】都應該初始化為 解決問題時有兩種情況, (1)當前揹包容量不足以放入i(j<wi),那麼V【i,j】=V【i-1,j】 (2)當前揹包容量足以放入i(j>=wi),此時要選擇i放還是不放,如果不放V【i,j】=V【i-1,j】;如果放V【i,j】=V【i-1,j-wi】+vi。取兩者之間的那個較大的值 狀態轉移方程
if(j>=w[i]) m[i][j]=max(m[i-1][j],m[i-1][j-w[i]]+v[i]); else m[i][j]=m[i-1][j];
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 0 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 |
2 | 0 | 0 | 0 | 0 | 8 | 8 | 10 | 10 | 10 | 10 | 18 | 18 | 18 |
3 | 0 | 0 | 6 | 6 | 8 | 8 | 14 | 14 | 16 | 16 | 18 | 18 | 24 |
4 | 0 | 0 | 6 | 6 | 9 | 9 | 14 | 14 | 17 | 17 | 19 | 19 | 24 |
5 | 0 | 0 | 6 | 6 | 9 | 9 | 14 | 14 | 17 | 17 | 19 | 21 | 24 |
6 | 0 | 2 | 6 | 8 | 9 | 11 | 14 | 16 | 17 | 19 | 19 | 21 | 24 |
程式碼: (程式碼是以6個物品為例的)
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <map> #include <set> #include <queue> #include <deque> #include <algorithm> using namespace std; #define memset(a,n) memset(a,n,sizeof(a)) #define PI acos(-1) typedef long long ll; int dp[7][10000+5]; int w[7]; int v[7]; int main() { int t,m; scanf("%d",&t); while(t--) { memset(dp,0); scanf("%d",&m); for(int i=1; i<=6; i++) scanf("%d",&w[i]); for(int i=1;i<=6;i++) scanf("%d",&v[i]); for(int i=1; i<=6; i++) for(int j=1; j<=m; j++) { if(j<w[i]) dp[i][j]=dp[i-1][j]; else dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]); } printf("%d\n",dp[6][m]); } }