給你n種不同的物品,每個物品有自己的重量w[i],和價值v[i],如果每個物品只能拿一次,給你容量為m的揹包,怎樣才能取得最大價值?
狀態轉移方程:dp[j]=max
基本操作:
for
(i=0
;i)for
(j=m;j>=w[i]
;j--
)//01是從最大到當前
dp[j]
=max
(dp[j]
,dp[j-w[i]
]+v[i]
);
dp[j]用來記錄當容量為j時的可行取法的最大價值。
給你n種不同的物品,每個物品有自己的重量w[i],和價值v[i],如果每個物品最多只能拿c[i]個,給你容量為m的揹包,怎樣才能取得最大價值?
狀態轉移方程:dp[j]=max;
但是一般會t,所有要用二進位制或者拆分01完全優化
二進位制優化
for
(i=0
;im=c[i]
-k+1
;for
(j=v;j>=m*v[i]
;j--
)}
coins那道題的板子,01拆分後二進位制優化了
#include
#include
#include
#define inf 0x3f3f3f3f
using namespace std;
//手錶**
int m;
//單位貨幣的價值
int val[
1005];
//單位貨幣的數量
int vol[
1005];
int dp[
100005];
void
zero
(int cost)
//val*vol>>m,硬幣可以無限使用,可以使用完全揹包
void
com(
int cost)
//拆分vol,**係數k*vol組成新硬幣
void
mul(
int val,
int vol)
zero
(vol*val);}
}int
main()
return0;
}
給你n種不同的物品,每個物品有自己的重量w[i],和價值v[i],乙個物品可以拿多次,給你容量為m的揹包,怎樣才能取得最大價值?
分析:類似於01揹包問題,在01揹包問題中,物品要麼取,要麼不取,而在完全揹包中,物品可以取0件、取1件、取2件…直到揹包放不下位置。因此,可以直接在01揹包的遞推式中擴充套件得到。
狀態轉移方程:dp[j]=max
基本操作:
for
(i=1
;i<=n;i++
)for
(j=w[i]
;j<=m;j++
)//注意此處與01揹包不同,01為倒序
dp[j]
=max
(dp[j]
,dp[j-w[i]
]+v[i]
);
乙個簡單有效的優化
完全揹包問題有乙個很簡單有效的優化,是這樣的:若兩件物品i、j滿足c[i]<=c[j]且w[i]>=w[j],則將物品j去掉,不用考慮。這個優化的正確性顯然:任何情況下都可將價值小費用高得j換成物美價廉的i,得到至少不會更差的方案。對於隨機生成的資料,這個方法往往會大大減少物品的件數,從而加快速度。
揹包 01揹包,完全揹包,多重揹包
哈哈 01揹包 f i v max 完全揹包 f i v max 多重揹包 f i v max include include include include include define maxn 1000 using namespace std int n,cap int w maxn 重量 花...
01揹包 完全揹包 多重揹包
01揹包 zeroonepack 有n件物品和乙個容量為v的揹包,每種物品均只有一件。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。include include includeusing namespace std const int n 1000 10 int ...
01揹包 完全揹包 多重揹包
01揹包 zeroonepack 有n件物品和乙個容量為v的揹包。每種物品均只有一件 第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。完全揹包 completepack 有n種物品和乙個容量為v的揹包,每種物品都有無限件可用。第i種物品的費用是c i 價值是w i 求...