感謝趙宗昌老師
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開始用 ...