整理自 杭州電子科大劉春英老師PPT及《揹包九講》崔天翼ios
給你一個容量爲V的揹包和若干種物品,在必定的限制條件下(每種物品都佔用必定容量),問最多能放進多少價值的物品?spa
和動態規劃的聯繫:揹包的每一個容量就是「狀態」,選擇每一個物品就是「狀態的決策」。code
問題描述ip
有N件物品和一個容量爲V的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可以使價值總和最大。ci
問題特色get
每種物品僅有一件,能夠選擇放或不放,用子問題定義狀態:即f[i][v]表示前i件物品恰放入一個容量爲v的揹包能夠得到的最大價值。string
狀態轉移方程產品
\(f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}\)it
問題描述io
有N種物品和一個容量爲V的揹包,每種物品都有無限件可用。第i種物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可以使這些物品的費用總和不超過揹包容量,且價值總和最大。
問題特色
按照01思路的想法,策略從取或者不取變成每種取多少個
狀態轉移方程
\(f[i][v]=max{f[i-1][v-kc[i]]+kw[i] | 0\ge kc[i]\le v}\)
問題描述
有 N 種物品和一個容量爲 V 的揹包。第 i 種物品最多有 M i 件可用,每件耗費的
空間是 \(C_i\) ,價值是 \(W_i\) 。求解將哪些物品裝入揹包可以使這些物品的耗費的空間總和不超
過揹包容量,且價值總和最大。
#include <iostream> #include <cstring> #define maxn 1010 using namespace std; int volume[maxn]={0}; int value[maxn]={0}; int dp[maxn]={0}; int main(){ int t,n,v,i,j; cin >> t; while(t--){ memset(volume,0,sizeof(volume)); memset(value,0,sizeof(value)); memset(dp,0,sizeof(dp)); cin >> n >> v; for(i=0;i<n;i++) cin >> value[i]; for(i=0;i<n;i++) cin >> volume[i]; if(n==0 || v==0){ cout << '0'<< endl; continue; } for(i=0;i<n;i++){ for(j=v;j>=volume[i];j--){ dp[j] = max(dp[j],dp[j-volume[i]]+value[i]); } } cout << dp[v] << endl; } }
#include <iostream> #include <cstring> #define maxn 10001 using namespace std; int cost[3]={150,200,350}; int value[3]={150,200,350}; int dp[maxn]={0}; int main(){ int t,n,i,j,out=0; cin >> t; while(t--){ out = 0; memset(dp,0,sizeof(dp)); cin >> n; if(n<150){ cout << n << endl; continue; } for(i=0;i<3;i++){ for(j=0;j<=n;j++){ if(j>=cost[i]){ dp[j] = max(dp[j],dp[j-cost[i]]+value[i]); out = max(out,dp[j]); } } } cout << n-out << endl; } }
(HDU2191)急!災區的食物依然短缺!
爲了挽救災區同胞的生命,心繫災區同胞的你準備本身採購一些糧食支援災區,如今假設你一共有資金n元,而市場有m種大米,每種大米都是袋裝產品,其價格不等,而且只能整袋購買。
請問:你用有限的資金最多能採購多少公斤糧食呢?
思路一:轉化爲01揹包問題,把全部的物品都做爲候選項,判斷這個物體是否放;簡單直觀;
#include <iostream> #include <cstring> using namespace std; struct rice{ int p; int h; int c; }rices[2001]; int c,n,m,num,i,j; int dp[2001]={0}; int main(){ cin >> c; while(c--){ memset(dp,0,sizeof(dp)); memset(rices,0,sizeof(rices)); cin >> n >> m; for (i=0,j=0;i<m;i++,j++){ cin >> rices[j].p; cin >> rices[j].h; cin >> num; for (int k=0;k<num-1;k++){ rices[k+1+j].p = rices[j].p; rices[k+1+j].h = rices[j].h; } j += num-1; } num = j; int maxo = 0; for(int i=0;i<num;i++){ for(int j=n;j>=rices[i].p;j--){ dp[j] = max(dp[j],dp[j-rices[i].p]+rices[i].h); //maxo = max(maxo,dp[j]); } } cout << dp[n] << endl; } }