第三讲 多重背包问题①——转化

【题目来源】AcWing 4. 多重背包问题 I

在这里插入图片描述
【题意分析】和完全背包问题类似,但是区别在于每一种物品的数量是有限的。
【解决方法】
1.转化为 0 / 1 0/1 0/1 背包问题
因为每一种物品数量有限,所以将每个物品看作单独的种类,可转化为 0 / 1 0/1 0/1 背包问题,如下表所示:

正确输入数据:

for(int i = 1; i <= n; i ++){
  int a, b, c;
  cin >> a >> b >> c;
  for(int j = 1; j <= c; j ++)
    q[++ m].v = a, q[m].w = b;
}
for(int i = 1; i <= m; i ++)
  for(int j = V; j >= q[i].v; j --)
    dp[j] = max(dp[j], dp[j - q[i].v] + q[i].w);
cout << dp[V];
//时间复杂度:O(n^3) = 10^6,1000ms能过。

2.转化为 0 / 1 0/1 0/1 背包和完全背包问题
当有一种物品的个数,多于或等于背包完全装该种物品的数量时,此时相当于完全背包,即
q [ i ] . s > = V / q [ i ] . v ⇒ q [ i ] . s ∗ q [ i ] . v > = V q[i].s >= V / q[i].v ⇒ q[i].s * q[i].v >= V q[i].s>=V/q[i].vq[i].sq[i].v>=V
当不满足时,为 0 / 1 0/1 0/1 背包,代码如下:

int main(){
  cin >> n >> V;
  for(int i = 1; i <= n; i ++){
    cin >> q[i].v >> q[i].w >> q[i].s;
    if(q[i].s * q[i].v >= V)  //完全背包问题 
      for(int j = q[i].v; j <= V; j ++)
        dp[j] = max(dp[j], dp[j - q[i].v] + q[i].w);
    else  //0/1背包问题 
      for(int j = V; j >= q[i].v; j --)
        for(int k = q[i].s; k >= 0; k --)
          if(j >= k * q[i].v)
            dp[j] = max(dp[j], dp[j - k * q[i].v] + k * q[i].w);      
  cout << dp[V];
  return 0;
}
//时间复杂度:O(n^3) = 10^6,1000ms能过。
  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值