【2019寒假集训DAY1】背包问题
基本信息
- 金矿模型理解:http://www.cnblogs.com/sdjl/articles/1274312.html
- 适用条件: 重叠子结构、最优子问题、边界、子问题独立+转移方程式
- 背包九讲(结合题目):http://www.cnblogs.com/jbelial/articles/2116074.html
- 框架
01背包问题:
无优化
for(int i=1;i<=n;i++) { for(int c=0;c<=m;c++) { f[i][c]=f[i-1][c]; if(c>=w[i]) f[i][c]=max(f[i][c],f[i-1][c-w[i]]+v[i]); } }
一维数组优化:
for(int i=1;i<=n;i++) { for(int c=m;c>=0;c--) { if(c>=w[i]) f[c]=max(f[c],f[c-w[i]]+v[i]); } }
更进一步的常数优化:
for(int i=1;i<=n;i++) { sumw+=w[i]; bound=max(m-sumw,w[i]); for(int c=m;c>=bound;c--) { if(c>=w[i]) f[c]=max(f[c],f[c-w[i]]+v[i]); } }
完全背包问题:
for(int i=1;i<=n;i++) { for(int c=0;c<=m;c++) { if(c>=w[i]) f[c]=max(f[c],f[c-w[i]]+v[i]); } }
多重背包问题:
for(int i=1;i<=n;i++) { if(w[i]*a[i]>m) { for(int c=0;c<=m;c++) { if(c>=w[i]) f[c]=max(f[c],f[c-w[i]]+v[i]); } } else { k=1;amount=a[i]; while(k<amount) { for(int c=k*w[i];c>=0;c--) { if(c>=w[i]) f[c]=max(f[c],f[c-w[i]]+k*v[i]); } amount-=k; k<<=1; } for(int c=amount*w[i];c>=0;c--) { f[c]=max(f[c],f[c-w[i]]+amount*v[i]); } } }
01背包
- 理解:https://www.cnblogs.com/arsenalfaninecnu/p/8945548.html
- 洛谷: