浅谈多重背包及其优化

模板来源:codevs 5429

根据背包问题的相关状态转移方程,我们不难写出朴素的算法

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 inline int read() {
 7     int ret=0;
 8     int op=1;
 9     char c=getchar();
10     while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();}
11     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
12     return ret*op;
13 }
14 int n,m;
15 int c[7010],v[7010],num[7010];
16 int f[7010];
17 int main() {
18     n=read(); m=read();
19     for(int i=1;i<=n;i++) {
20         c[i]=read(); v[i]=read(); num[i]=read();
21     }
22     for(int i=1;i<=n;i++)
23         for(int j=m;j>=c[i];j--)
24             for(int k=0;k<=num[i];k++)
25                 if(j-c[i]*k>=0)
26                     f[j]=max(f[j],f[j-c[i]*k]+v[i]*k);
27     printf("%d\n",f[m]);
28     return 0;
29 }
TLE Code

在朴素算法中,我们枚举每个物品的数量作为决策,这样大大浪费时间,我们可以将物品二进制拆分来代替枚举,具体地讲,例如某种物品数量为10,那么我们将这个物品的数量拆分成1,2,4,3(相当于把这个数量为10的物品分成四个物品),然后这个问题就转化成了01背包问题。时间复杂度大大降低。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 inline int read() {
 7     int ret=0;
 8     int op=1;
 9     char c=getchar();
10     while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();}
11     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
12     return ret*op;
13 }
14 int n,m,tot;
15 int f[7010],c[100010],v[100010];
16 int main() {
17     n=read(); m=read();
18     for(int i=1;i<=n;i++) {
19         int    x=read(),y=read(),z=read();
20         int base=1;
21         while(z>=base) {
22             c[++tot]=x*base;
23             v[tot]=y*base;
24             z-=base;
25             base<<=1;
26         }
27         if(z>0) {
28             c[++tot]=z*x;
29             v[tot]=z*y;
30         }
31     }
32     for(int i=1;i<=tot;i++)
33         for(int j=m;j>=c[i];j--)
34             f[j]=max(f[j],f[j-c[i]]+v[i]);
35     printf("%d\n",f[m]);
36     return 0;
37 }
TLE Code better

 我们继续考虑优化dp,我们将状态j按照c[i]的余数分组,显然,当i为定值时,不同组的状态不能相互转移。

我们将倒序循环j的过程,改为对每个余数u∈[0,c[i]-1],倒序循环p,这样状态j=u+p*c[i]。

 于是我们得到了新的状态转移方程:

 类比Fence一题,我们便可以使用单调队列进行优化,这种算法的时间复杂度与普通的背包相等,可以通过本题。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 int n,m,c[7010],v[7010],num[7010],f[7010];
 8 int q[7010];
 9 inline int read() {
10     int ret=0;
11     int op=1;
12     char c=getchar();
13     while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();}
14     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
15     return ret*op;
16 }
17 inline int calc(int i,int u,int k) {
18     return f[u+k*c[i]]-k*v[i];
19 }
20 int main() {
21     n=read(); m=read();
22     memset(f,0xcf,sizeof(f));
23     f[0]=0;
24     for(int i=1;i<=n;i++) {
25         c[i]=read(); v[i]=read(); num[i]=read();
26         for(int u=0;u<c[i];u++) {
27             int l=1,r=0;
28             int maxx=(m-u)/c[i];
29             for(int k=maxx-1;k>=max(0,maxx-num[i]);k--) {
30                 while(l<=r&&calc(i,u,q[r])<=calc(i,u,k)) r--;
31                 q[++r]=k;
32             }
33             for(int p=maxx;p>=0;p--) {
34                 while(l<=r&&q[l]>p-1) l++;
35                 if(l<=r) f[u+p*c[i]]=max(f[u+p*c[i]],calc(i,u,q[l])+p*v[i]);
36                 if(p-num[i]-1>=0) {
37                     while(l<=r&&calc(i,u,q[r])<=calc(i,u,p-num[i]-1)) r--;
38                     q[++r]=p-num[i]-1;
39                 }
40             }
41         }
42     }
43     int ans=0;
44     for(int i=1;i<=m;i++)
45         ans=max(ans,f[i]);
46     printf("%d\n",ans);
47     return 0;
48 }
AC Code

 

转载于:https://www.cnblogs.com/shl-blog/p/10990625.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/483203.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人脑计划:大脑研究如何对超级计算提出新要求

来源&#xff1a;ScienceAI编译&#xff1a;绿萝「了解大脑的所有复杂性需要从多个尺度——从基因组学、细胞和突触到整个器官水平的洞察力。这意味着处理大量数据&#xff0c;超级计算正在成为解决大脑问题的不可或缺的工具。」人类大脑项目 (HBP) 科学主任、杜塞尔多夫大学和…

数据结构与算法——递归、回溯与分治

文章目录1.预备知识1.1 递归1.2 回溯1.3 位运算2.子集2.1 题目描述2.2 解题思路——回溯递归法2.3 C实现2.4 解题思路——位运算法2.5 位运算实现3.子集 II3.1 题目描述3.2 解题思路3.3 回溯递归法——C实现3.4 位运算——C实现4.组合总和 II4.1 题目描述4.2 解题思路4.3 C实现…

MongoDB安装启动教程

MongoDB安装启动教程 简易教程&#xff1a;鉴于第一次大家使用分布式数据库&#xff0c;提供一个简易教程&#xff08;也可看老师的PPT或者视频&#xff09; 1.点击安装包&#xff08;老师给的&#xff09;&#xff0c;安装目录不要更改&#xff0c;否则后面配置需要改&#xf…

机器能思考吗?

来源&#xff1a;人机与认知实验室机器有智能吗&#xff1f;机器会理解吗&#xff1f;机器能思考吗&#xff1f;从十七世纪到今&#xff0c;每一次机器功能的重大突破&#xff0c;这问题都被翻出来问一遍&#xff0c;只是否定它变得愈来愈困难了。Alpha Go与李世石的围棋赛尘埃…

数据结构与算法——二叉树与图

文章目录1.预备知识1.1 二叉树定义1.2 二叉树的构造2.路径总和 II2.1 题目描述2.2 算法思路2.3 C实现3.二叉树的最近公共祖先3.1 题目描述3.2 解题思路3.3 C实现4.二叉树展开为链表4.1 题目描述4.2 思考4.3 C实现4.4 解法二4.5 C实现5.二叉树的右视图5.1 预备知识5.2 题目描述5…

Nature评论:机器学习的物理启示录——隔壁的另一条机遇之道

来源&#xff1a;AI科技评论作者&#xff1a;Don编辑&#xff1a;青暮老话说&#xff1a;隔行不取利。但时过境迁&#xff0c;目前不管是娱乐圈还是学术界&#xff0c;跨界方可大红大紫。在娱乐圈&#xff0c;相声演员客串脱口秀&#xff0c;歌手跨界演员&#xff0c;赚的钵满盆…

操作系统——文件的逻辑结构

文章目录1.文件的逻辑结构的概念1.1 按照逻辑结构的文件分类1.2 无结构文件和有结构文件的区别2 顺序文件3 索引文件4.索引顺序表1.文件的逻辑结构的概念 1.1 按照逻辑结构的文件分类 1.2 无结构文件和有结构文件的区别 2 顺序文件 3 索引文件 4.索引顺序表

操作系统——文件目录

文章目录1.文件目录知识点2. 文件分配方式3.文件的存储空间管理4.文件的基本操作5.文件共享6.文件保护7.文件系统的层次结构1.文件目录知识点 2. 文件分配方式 3.文件的存储空间管理 4.文件的基本操作 5.文件共享 6.文件保护 7.文件系统的层次结构

我们不知道答案的125个科学问题(16)群体合作行为的演化

来源&#xff1a;张林科学网博客链接地址&#xff1a;http://blog.sciencenet.cn/blog-318012-1292142.html题记&#xff1a;离Science杂志提出125个问题到今天已经过去了16个年头&#xff0c;然而我这个125个问题的系列解读仅仅进行到第16个&#xff0c;想必这125个问题自己也…

Nature:大脑空间导航研究五十年

来源&#xff1a;集智俱乐部作者&#xff1a;Isabel I. C. Low & Lisa M. Giocomo译者&#xff1a;赵雨亭 审校&#xff1a;张澳 编辑&#xff1a;邓一雪 导语老马识途的故事被人们所熟知&#xff0c;但其识途的神经机制却尚待研究。1971年&#xff0c;研究人员首次发现&am…

操作系统——磁盘

文章目录1.磁盘的结构2.磁盘调度算法3.减少磁盘延时时间的方法4.磁盘管理1.磁盘的结构 2.磁盘调度算法 3.减少磁盘延时时间的方法 4.磁盘管理

建网站如何选择好用的网站源码程序

很多新手朋友第一次建网站时候&#xff0c;如何选择一款适合的网站源码是比较困惑的问题&#xff0c;选择一款好的网站源码可以节约大量时间和金钱&#xff0c;但是由于网站源码参差不齐&#xff0c;免费的&#xff0c;收费的&#xff0c;淘宝几元钱购买的&#xff0c;几万块钱…

操作系统——设备管理

文章目录1.I/O设备的基本概念与分类2.I/O控制器3.I/O控制方式4.I/O软件层次结构5.I/O核心子系统6.假脱机技术7.设备的分配和回收8.缓冲区管理1.I/O设备的基本概念与分类 2.I/O控制器 3.I/O控制方式 4.I/O软件层次结构 5.I/O核心子系统 6.假脱机技术 7.设备的分配和回收 8.缓冲区…

95页重磅报告:全面预测未来5年趋势

来源&#xff1a;中产财富分水岭将成为未来5年中国互联网的关键词&#xff0c;从浅水区向深水区过渡&#xff0c;引发竞争格局的强弱式转化。分水岭期不存在直道竞争&#xff0c;冷静和变化成为主旋律。版权申明&#xff1a;内容来源网络&#xff0c;版权归原创者所有。除非无法…

新发现为类脑计算机开辟了道路

来源&#xff1a;ScienceAI编辑&#xff1a;萝卜皮大型自旋霍尔纳米振荡器&#xff08;SHNO&#xff09;阵列的同步&#xff0c;是实现超快非常规计算的一种有吸引力的方法。然而&#xff0c;与阵列接口、调整其单个振荡器和提供内置存储器单元仍然存在巨大的难题。瑞典哥德堡大…

互联网大脑如何产生“梦境“并形成元宇宙

作者&#xff1a;刘锋本文摘录自2019年中信出版社出版的《崛起的超级智能&#xff0c;互联网大脑如何影响科技未来》的第二章“10条规则&#xff1a;互联网大脑如何影响科技企业的命运”中的“第九条规则&#xff0c;互联网大脑梦境的构建带来产业升级”。这一节详细阐述了互联…

2022年人工智能领域发展七大趋势

来源&#xff1a;科技日报编辑&#xff1a;蒲蒲美国《福布斯》网站在近日的报道中指出&#xff0c;尽管目前很难想象机器自主决策所产生的影响&#xff0c;但可以肯定的是&#xff0c;当时光的车轮到达2022年时&#xff0c;人工智能领域新的突破和发展将继续拓宽我们的想象边界…

数据库基础知识——DQL语言(一)

文章目录1.基础查询2.条件查询3.排序查询4.常见函数4.1 单行函数4.1.1 字符函数4.1.2 数学函数4.1.3 日期函数4.1.4 流程控制函数4.1.5 其他函数4.2 分组函数/统计函数/聚合函数5.分组查询1.基础查询 语法&#xff1a; SELECT 要查询的东西 【FROM 表名】;#查询employees表中所…

周志华教授发表首届国际学习与推理联合大会IJCLR开场Keynote:探索从纯学习到学习+推理的AI...

周志华&#xff0c;毕业于南京大学&#xff0c;欧洲科学院外籍院士&#xff0c;国家杰出青年基金获得者&#xff0c;现任南京大学人工智能学院院长、南京大学计算机软件新技术国家重点实验室常务副主任、机器学习与数据挖掘研究所 (LAMDA)所长、人工智能教研室主任。2021年8月1…

第八章 指针实验

C程序实验报告 实验项目&#xff1a; 1、指针基础及指针运算 2、数据交换 3、字符串反转及字符串连接 4、数组元素奇偶排列 姓名&#xff1a;曹时仙 实验地点&#xff1a;教学楼514教室 实验时间&#xff1a;2019.6.12 一、实验目的与要求 1、掌握指针的概念和定义方法 2、掌…