背包问题
dd_engi 的背包九讲
背包问题
P1-01背包
每种物品仅有一件,每件有 \(v[i]\) 的体积,\(w[i]\) 的价值,背包容量一共为V,每件物品可以选择放或者不放
求最大可获得的价值
f[i][v]=max(f[i-1][v],f[i-1][v-c[i]]+w[i]);
\(f[i][v]\)=前 \(i\) 件物品放进容量 \(V\) 的背包的最大价值
一维
for(i=1;i<=n;i++)
for(v=V;v>=c[i];v--)
f[v]=max(f[v],f[v]-c[i]+w[i]);
初始化
如果恰好装满 f[0]=0; f[1...V]=INF; \(^1\)
没必要装满 f[]={0}; \(^2\)
相当于
\(^1\) 不装物品时,只有f[0]=0 合法,其它全部非法
\(^2\) 不装物品时,全部合法
P2-完全背包
同01背包。每种物品有无限件
f[i][v]=max(f[i-1][v-k*c[i]]+k*w[i]); \(k*c[i]\in[0,v]\)
优化
若 c[i]<=c[j]&&w[i]>=w[j] 那么 \(j\) 可以删除
可以被构造的数据卡成没有优化
玄学(数据)优化
转化成01背包
for(i=1;i<=n;i++)
for(v=c[i];v<=V;v++)
f[v]=max(f[v],f[v]-c[i]+w[i]);
P3-多重背包
同01背包。第 \(i\) 件物品最多可选 \(n[i]\) 次
f[i][v]=max(f[i-1][v-k*c[i]]+k*w[i]); \(k\in[0,n[i]] \quad k*c[i]\in[0,v]\)
转化成01背包
将第 \(i\) 种物品换成 \(n[i]\) 件01背包里的物品
复杂度没变 为 \(O(V*\sum n[i])\)
可以将 \(n[i]\) 个物品分成取 \(1,2,4,8...,(n-2^k+1)\)
多重背包(cost,weight,amount) //amount表示物品的数量
{
if(cost*amount>=V)
{
完全背包(cost,weight)
break;
}
int k=1;
while(k<num)
{
01背包(k*cost,k*weight)
amount-=k;
k<<=1;
}
}
P4-混合背包
同时具有P1 P2 P3的所有要求
for(i=1;i<=n;i++)
{
if(P1)
//....
if(P2)
//....
if(P3)
//....
}
P5-二维费用的背包
同01背包。对于一个物品 \(i\) ,需要付出 \(v'[i]\) 和\(u'[i]\) 的价值,对应 \(U\) 和 \(V\)
f[i][v][u]=max(f[i-1][v][u],f[i-1][v-v'[i]][u-u'[i]]+w[i]);
\(f[i][v][u]\)=前 \(i\) 件物品放进容量 \(V\) 代价 \(U\) 的背包的最大价值
对于限制的要求,对应P2 P3 P4 时,参考该题写法
P6-分组背包
同01背包。这些物品被划分成 \(K\) 组,每组最多取一件
f[k][v]=max(f[k-1][v],f[k-1][v-c[i]]+w[i]); \(k\in[0,n[i]] \quad k*c[i]\in[0,v] \quad 物品[i]\in 组[k]\)
\(f[k][v]\) 对于一组:选择一件或者一件都不选
for(k=1;k<=K;k++)
for(v=V;v>=c[i];v++)
for(i=1;i属于k;i++)
f[v]=max(f[v],f[v-c[i]]+w[i]);
玄学优化同P2
P7-有依赖的背包
同01背包。依赖:对于一些物品 \(j\) ,选择 \(j\) 前必须选择 \(i\) ,有些物品有依赖有些没有,没有一件物品同时依赖于多件物品。设没有依赖的物品为主件,其余为附件。
主件及附件的集合相当于P6里的组,可以 不取 或 取主件 或 取主件+附件 ,但是这样有\(2^{n+1}\)种策略
参考P6及P2的玄学优化
优化指出:对于一个组中的物品,所有费用相同的情况可以只保留一个价值最大的而不影响结果
所以可以对主件 \(i\) 的附件集合做一次01背包,求出 \(0...V-c[i]\) 时的最大价值 \(f'[0...v-c[i]]\) ,然后将主件 \(i\) 转化成 \(V-c[i]+1\) 个物品的组,然后做P6-分组背包即可以求解
对于背包九讲的P8 P9 鸽.....

浙公网安备 33010602011771号