首页 > 其他分享 >关于 多重背包

关于 多重背包

时间:2022-10-09 22:00:48浏览次数:100  
标签:多重 cnt 背包 logS int 枚举 关于 物品

问题描述:

有 N 种物品和一个容量为 V 的背包,第 i 件物品最多有 S件。每件体积是 w[i] ,价值是 v[i] 。求解将哪些物品装入背包可使价值总和最大。


问题特点:

第 i 件物品最多有 S件,可以选择不超过 Si 件的 i 物品放入背包中。


朴素版方程:

可以利用完全背包的想法,很容易得到:

for(int i = 1; i <= n; i ++)
        for(int j = 0; j <= m; j ++)
            for(int k = 0; k <= s[i] && k * v[i] <= j; k ++)
                dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i] * k] + w[i] * k);

但时间复杂度过高( O(N*S*V) ),那么我们能不能像思考完全背包优化版那样来优化一下多重背包?


如何优化?

从状态转移方程入手,将其拆开:

可以发现,我们只能求出 max( dp[i,j-v] ) ,并不能求出橙色方框里的 max ,因此也就不能求出 max( dp[i,j] ) ,那么就不能直接利用完全背包的思想来解决。

这里呢就要用到一种比较神奇的优化方式了:二进制优化方式

假设第 i 个物品有 s=1023 个,那我们难道真的要一个一个枚举出来吗?傻子才这么做,正常人都这么想:

把若干个第 i 个物品打包一起考虑,假设分成10组,第一组1个,第二组2个,第三组4个,第四组8个,……第十组512个,每组最多只能选一次,然后看一下是否能从这十组中拼凑出从0~1023 中任何一个数呢?那当然是。因此,我们可以将每组看作成一个小的“01背包问题”,也就是用10个新的物品来表示原来的第 i 个物品,然后我们枚举新的物品选或者不选就可以拼凑出第 i 个物品的所有方案了。(从枚举1024次缩小成枚举十次,log(n)的做法。)

但是!比如 s=200,可以分成1、2、4、8、16、32、64,注意,不能分出第七组128,因为 i 最多只有200个,而从1加到128有255个。从1加到64是127,200-127=73,所以第七组被分成73个。

总结:如果我们有 S 个物品,那么我们可以拆分成 logS 组,也就相当于 logS(logS向上取整)个新物品,新物品只能用一次,对新物品做一次01背包问题

这样一来,由原先的复杂度 O(N*S*V) 优化成现在的时间复杂度 O(N*V*logS) 了。

最后也就是多了这些:

 1 int cnt = 0;//记录共有几组新物品
 2     for(int i = 1; i <= n; i ++)
 3     {
 4         int a, b, s;//价值、体积、个数
 5         cin >> a >> b >> s;
 6         int k = 1;
 7         while(k <= s)
 8         {
 9             cnt ++;
10             v[cnt] = a * k;
11             w[cnt] = b * k;
12             s -= k;
13             k *= 2;
14         }
15         if(k > 0)
16         {
17             cnt ++;
18             v[cnt] = a * s;
19             w[cnt] = b * s;
20         }
21     }
22 
23     n = cnt;

模板题:5. 多重背包问题 II - AcWing题库

 

标签:多重,cnt,背包,logS,int,枚举,关于,物品
From: https://www.cnblogs.com/marswithme/p/16756244.html

相关文章

  • 关于名校的一个呼吁
    写一篇特殊的文章, 提一个大胆的想法,其实挺想呼吁中国知名高效的教授,能够做录播课程,只有这样,才能让教学资源利用最大化。不管在什么学校,大家能够一样学到名校的课程。至少......
  • 关于吐槽小白装机
    小白系统自来素称一键装机,使用方便,效率快捷,也是我最喜欢的装机工具。但是时隔多年,我转行已久,再次需要装系统时,才发现惊心一幕。我买了一个比较大的sata机械硬盘(白盘),打算装......
  • 关于CPM_PCIE_NOC_0/1有关描述
    关于CPM_PCIE_NOC_0/1有关描述                    个人理解:CPM_PCIE_NOC_0/1与C2H,H2CStream接口实现的功能一样,即PCIE传输......
  • 关于TCP和UDP的联系与区别以及网络字节序和主机字节序的转换函数实践
    1.TCP和UDP的相同点:TCP和UDP都是在网络层,都是传输层协议,都能都是保护网络层的传输,双方的通信都需要开放端口。2.TCP和UDP的不同点:TCP传输协议,是一种面向连接的、可靠的......
  • 从零开始配置vim(25)——关于 c++ python 的配置
    从9月份到国庆这段时间,因为得了女儿,于是回老家帮忙料理家事以及陪伴老婆和女儿。一时之间无暇顾及该系列教程的更新。等我回来的时候发现很多小伙伴私信我催更。在这里向支......
  • 最近整理的关于 FastAdmin 开源的文章
    最近整理的关于FastAdmin开源的文章《FastAdmin开源后的惊喜》《在FastAdmin社区如何快速获得答案?》《FastAdmin有些插件为什么要收费?》《开源是什么?(FastAdmin......
  • 关于Microsoft Office Outlook-邮件搜索方法记录
     Outlook(MicrosoftOffice套装软件组件)一般指MicrosoftOutlookMicrosoftOfficeOutlook是微软办公软件套装的组件之一,它对Windows自带的Outlookexpress的功能进行了扩......
  • 关于对拍
    其实只需要再额外写一个自动对拍的程序就可以了#include<cstdio>#include<cstdlib>#include<ctime>usingnamespacestd;intmain(){while(1)//一直循环,直......
  • 关于贪心策略的一些小trick
    为什么要写这种如此简单的东西呢就是因为菜啊首先给出关于贪心的三个定义符合贪心选择的特性(GreedyChoiceProperty)我们需要证明我们的第一个选择(贪心选择GreedyCho......
  • 转载:关于vscode(Visual Studio Code)编写c语言 中文乱码问题
    关于vscode(VisualStudioCode)编写c语言中文乱码问题。处理方法:选择菜单File > Preferences >Settings,找到TextEditor>Files中的Encoding,更改为Simplified......