揹包問題入門記錄

2022-05-08 06:24:13 字數 2325 閱讀 1816

感謝趙宗昌老師

01揹包

//

01 暴力

void dfs(int i,int j,int s)

dfs(i+1,j,s);//

不選if(j>=w[i]) dfs(i+1,j-w[i],s+c[i]);//

能裝下就選物品i

}int

main()

//01 二進位制列舉

int k=1

if(w<=m) ans=max(ans,c);

} cout

o(2^n) 適合n<=20

//01-1

for(int i=1;i<=n;i++)//

前i個物品用了j的容量

for(int j=0;j<=m;j++)

f[i][j]=f[i-1

][j];

if(j>w[i]) f[i][j]=max(f[i][j],f[i-1][j-w[i]+c[i]);

//01-2

for(int i=1;i<=n;i++)

for(int j=0;j<=m;j++)

for(int k=0;k<=1;k++)

if(j>k*w[i]) f[i][j]=max(f[i][j],f[i-1][j-w[i]*k]+k*c[i]);

//01-3滾動陣列

for(int i=1;i<=n;i++)

for(int j=m;>=w[i];j--)//

防止乙個物品選多次

f[j]=max(f[j],f[j-w[i]]+c[i]);

cout

<

完全揹包

//完全-1

for(int i=1;i<=n;i++)

for(int j=0;i<=m;j++)

//完全-2

for(int i=1;i<=n;i++)

for(int j=0;j<=m;j++)

for(int k=0;k<=j/w[i];k++)

f[i][j]=max(f[i][j],f[i-1][j-k*w[i]]+k*c[i]);

//完全-3

for(int i=1;i<=n;i++)

for(int j=w[i];j<=m;j++)

f[j]=max(f[j],f[j-w[i]+c[i]);

完全揹包問題轉化為01揹包問題來解。

最簡單的想法是,考慮到第i種物品最多選v/w[i]件,於是可以把第i種物品轉化為v/w[i]件費用及價值均不變的物

品,然後求解這個01揹包問題。這樣完全沒有改進基本思路的時間複雜度,但這畢竟給了我們將完全揹包問題轉化

為01揹包問題的思路:將一種物品拆成多件物品。

高效的轉化方法是:把第i種物品拆成費用為w[i]*2^k、價值為c[i]*2^k的若干件物品,其中k滿足w[i]*2^k多重揹包

//

多重揹包-1 ->完全揹包

//o(v*σs[i])

for(int i=1;i<=n;i++)

for(int j=0;j<=v;j++)

for(int k=0;k<=s[i];k++)

if(j>=k*w[i]) f[i][j]=max(f[i][j],f[i-1][j-k*w[i]]+k*c[i]);

//滾動陣列

for(int i=1;i<=n;i++)

for(int j=v;j>=0;j--)

for(int k=0;k<=s[i];k++)

if(j>=k*w[i]) f[j]=max(f[j],f[j-k*w[i]]+k*c[i]);

//多重揹包-2 ->01揹包+滾動陣列

//第i件物品,看做s[i]件一樣的物品i,變成了s[1]+..+s[n]件物品的0-1揹包,每個揹包取還是不取

//o(v*σs[i])

for(int i=1;i<=n;i++)

for(int j=1;j<=s[i];j++)

for(int k=v;k>=w[i];k--)

f[k]=max(f[k],f[k-j*w[i]]+j*c[i]);

//二進位制

//o(v*sum(log(s[i])))

for(int i=1;i<=n;i++)

z=z-k;

}}for(int i=1;i<=sn;i++)

for(int j=v;j>=w[i];j--)

f[j]=max(f[j], f[j-w[i]]+c[i]);

混合揹包一般完全揹包單獨求解,多重揹包和01揹包用01揹包求解

揹包問題入門

入門級別的乙個揹包問題 圖和解析都特別好 問題描述 給定n種物品和一揹包。物品i的重量是w i 其價值為v i 揹包的容量為c。問應如何選擇裝入揹包的物品,使得裝入揹包中物品的總價值最大?分析 對於一種物品,要麼裝入揹包,要麼不裝。所以對於一種物品的裝入狀態可以取0和1。設物品i的裝入狀態為xi,x...

Knapsack揹包問題入門

已知 揹包容量 c,物品種類 n,每種物品有且僅有1個 每種物品擁有負載 w 和 p 兩個屬性。設 n 1 2 維陣列,w p n first 物品n的負載 w p n second 物品n的 問題 揹包可裝物品的最大價值。求解 設 n 1 c 1 維陣列並初始化為0,v n c 表示 容量為 c ...

DP入門, 0 1揹包問題

hloj 1006 0 1揹包問題 hdu 2602 bone collector類似,但要注意輸入順序,問題規模,最重要的是重量為0的骨頭居然也有價值的!includeusing namespace std define n 401 define m 1501 int f n m 下標從1開始用 ...