【背包问题】

【01背包】

描述:给定物品总数\(n\),背包承重能力\(m\),物品价值\(v[i]\),物品重量\(w[i]\),求满足不超过背包承重能力的物品最大价值,每种物品只有一件。
解法:
\(f[i][j]\)表示前\(i\)个物品选择方案中总重为\(j\)时,物品的最大总价值。
那么转移方程为
\[f[i][j]=\max(f[i][j],f[i-1][j-w[i]]+v[i],f[i-1][j])\]
\(f[n][m]\)即为所求。

\(f[j]\)表示物品总重为\(j\)时,物品的最大总价值。
那么转移方程为

for(int i=1;i<=n;++i){//枚举物品
    for(int j=m;j>=w[i];--j){//枚举物品总重
        f[j]=max(f[j],f[j-w[i]]+v[i]);
    }
}

正确性:每次转移时\(f[j-w[i]]\)尚未被物品\(i\)尝试更新,故每个状态最多被当前物品更新一次。

【完全背包】

描述:给定物品总数\(n\),背包承重能力\(m\),物品价值\(v[i]\),物品重量\(w[i]\),求满足不超过背包承重能力的物品最大价值,每种物品有无限件。
解法:
\(f[i][j]\)表示前\(i\)种物品选择方案中总重为\(j\)时,物品的最大总价值。
那么转移方程为
\[f[i][j]=max(f[i][j],f[i][j-w[i]]+v[i],f[i-1][j])\]
\(f[n][m]\) 即为所求。

\(f[j]\)表示物品总重为\(j\)时,物品的最大总价值。
那么转移方程为

for(int i=1;i<=n;++i){
    for(int j=w[i];j<=m;++j){
        f[j]=max(f[j],f[j-w[i]]+v[i]);
    }
}

正确性:每次转移时\(f[j-w[i]]\)已经被物品\(i\)尝试更新,故每个状态会被物品尽可能多地更新(填满为止)。

猜你喜欢

转载自www.cnblogs.com/mhrlovezmy/p/9591996.html