背包问题之退背包

背包问题之退背包

退背包就是从可选物品中删除其中一个物品,问满足所取总价值为 j j j 的方案数。

像普通背包一样,退背包先普通dp以下,然后退去所选物品。

对于01背包,假设 d p [ i ] ​ dp[i]​ dp[i]为未退背包前满足所取总价值为 i ​ i​ i 的方案数。 d p ′ [ i ] ​ dp'[i]​ dp[i] 为退去第 x ​ x​ x个物品后满足所取总价值为 i ​ i​ i的方案数,那么 dp方程为

  • i < w [ x ] ​ ii<w[x]时, d p ′ [ i ] = d p [ i ] dp'[i]=dp[i] dp[i]=dp[i]
  • i ≥ w [ x ] ​ i\ge w[x]​ iw[x]时, d p ′ [ i ] = d p [ i ] − d p ′ [ i − w [ x ] ] ​ dp'[i]=dp[i]-dp'[i-w[x]]​ dp[i]=dp[i]dp[iw[x]]

代码表示:

for(int i=w[x];i<=m;++i) dp[i]-=dp[i-w[x]];

对于多重背包,假设 d p [ i ] dp[i] dp[i]为未退背包前满足所取总价值为 i i i 的方案数。 d p ′ [ i ] dp'[i] dp[i] 为退去第 x x x个物品后满足所取总价值为 i i i的方案数,那么 dp方程为

  • i < w [ x ] ​ ii<w[x]时, d p ′ [ i ] = d p [ i ] ​ dp'[i]=dp[i]​ dp[i]=dp[i]
  • i ≥ w [ x ] i\ge w[x] iw[x]时, d p ′ [ i ] = d p [ i ] − d p [ i − w [ x ] ] dp'[i]=dp[i]-dp[i-w[x]] dp[i]=dp[i]dp[iw[x]]

代码表示:

for(int i=m;i>=w[x];--i) dp[i]-=dp[i-w[x]];

不难看出,其实这就是普通背包DP过程的逆过程。

相关题目:

The Preliminary Contest for ICPC Asia Shanghai 2019 J. Stone game :传送门

你可能感兴趣的:(#,背包问题,比赛技巧)