背包问题

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 鸽.....

posted @ 2019-10-10 21:00  nenT  阅读(147)  评论(0)    收藏  举报