背包九讲
dp入门

dp[j] = max(dp[j], dp[j - c[i]] + v[i]);
}
}
i\j
j=0
i=0
0
j=1 j=2 j=3 j=4 j=5 j=6
0
00000i=10
3
6
9
12 15 18
i=2
0
3
6
10
13 16 20
17
多重背包
有n种物品,每种最多可以取x[i]个,每个物品有大小和价值,问总大小不超过m的情况下能取到最大的 价值是多少 代码如下: for (int i = 1; i <= n; ++i) {
} } 注意此时j一定是倒序产生
16
完全背包
有n种物品,每种最多可以取无数个,每个物品有大小和价值,问总大小不超过m的情况下能取到最大 的价值是多少
01背包中第二维改成正向即可:
for (int i = 1; i <= n; ++i) {
for (int j = c[i]; j <= m; ++j) {
}
10
数字三角形
线性DP解法 for(int i=m-1;i>0;i--) {
for(int j=0;j<=i;j++) { a[i-1][j]+=max(a[i][j],a[i][j+1]);
} }
11
数字三角形
暴力递归搜索解法: int dfs(int i, int j) {
if (i == n) return a[i][j]; return max(dfs(i+1,j), dfs(i+1,j+1)) + a[i][j]; }
背包九讲完整版

背包问题九讲 v1.0目录第一讲 01背包问题第二讲完全背包问题第三讲多重背包问题第四讲混合三种背包问题第五讲二维费用的背包问题第六讲分组的背包问题第七讲有依赖的背包问题第八讲泛化物品第九讲背包问题问法的变化附:USACO中的背包问题前言本篇文章是我(dd_engi)正在进行中的一个雄心勃勃的写作计划的一部分,这个计划的内容是写作一份较为完善的NOIP难度的动态规划总结,名为《解动态规划题的基本思考方式》。
现在你看到的是这个写作计划最先发布的一部分。
背包问题是一个经典的动态规划模型。
它既简单形象容易理解,又在某种程度上能够揭示动态规划的本质,故不少教材都把它作为动态规划部分的第一道例题,我也将它放在我的写作计划的第一部分。
读本文最重要的是思考。
因为我的语言和写作方式向来不以易于理解为长,思路也偶有跳跃的地方,后面更有需要大量思考才能理解的比较抽象的内容。
更重要的是:不大量思考,绝对不可能学好动态规划这一信息学奥赛中最精致的部分。
你现在看到的是本文的1.0正式版。
我会长期维护这份文本,把大家的意见和建议融入其中,也会不断加入我在OI学习以及将来可能的ACM-ICPC的征程中得到的新的心得。
但目前本文还没有一个固定的发布页面,想了解本文是否有更新版本发布,可以在OIBH论坛中以“背包问题九讲”为关键字搜索贴子,每次比较重大的版本更新都会在这里发贴公布。
目录第一讲 01背包问题这是最基本的背包问题,每个物品最多只能放一次。
第二讲完全背包问题第二个基本的背包问题模型,每种物品可以放无限多次。
第三讲多重背包问题每种物品有一个固定的次数上限。
第四讲混合三种背包问题将前面三种简单的问题叠加成较复杂的问题。
第五讲二维费用的背包问题一个简单的常见扩展。
第六讲分组的背包问题一种题目类型,也是一个有用的模型。
后两节的基础。
第七讲有依赖的背包问题另一种给物品的选取加上限制的方法。
第八讲泛化物品我自己关于背包问题的思考成果,有一点抽象。
计算机学习相关书籍

计算机学习相关书籍大学计算机专业使用的教材可以根据不同学校和课程有所不同,下面是楼主收集的一些经典(大部分是国外)的计算机专业教材:------C++------1.C++ Primer Plus C++ Primer习题集第5版,(美)李普曼,2.P520 C++ Primer(第5版)带书签高清完整版3.C++ Templates4.C++大学教程5.C++对象模型6.C++并发编程实战7.C++标准程序库—自修教程与参考手册8.C++沉思录中文第2版9.C++程序设计语言10.C++编程思想(两卷合订本)11.C++编程规范-101条规则准则与最佳实践12.C++编程调试秘笈13.C++设计新思维-泛型编程与设计之应用14.C++语言的设计和演化15.Effective C++ 中文版第三版高清PDF16.Effective STL中文版17.Modern C++ Design More18.Exceptional C++中文版19.STL源码20.STL源码剖析高清版(剖析+源码)21.提高C++性能的编程技术22.泛型编程与STL中文版23.深入理解C++1124.跟我一起写makefile------Go语言------1.Go并发编程实战2.Go语言圣经3.Go语言学习笔记4.Go语言实战5.Go语言标准库参考6.Go语言程序设计7.Go语言编程8.学习Go 语言(Golang)------Java------1.Head First Java 中文高清版2.Head First Servlet and JSP(高清中文版)3.java从入门到精通(第4版)4.JAVA并发编程实践5.Java性能优化权威指南6.Java核心技术卷1基础知识原书第10版7.Java核心技术卷2高级特性原书第10版8.大话java性能优化9.深入分析JavaWeb技术内幕10.深入剖析Tomcat 深入理解Java虚拟机:JVM高级特性与最佳实践(最新第二版)11.阿里巴巴Java开发手册--1------Java大数据------1.Apache Kafka实战2.Apache Spark源码剖析3.Apache+Kylin权威指南4.Elasticsearch集成Hadoop最佳实践5.Flink基础教程6.Flume构建高可用、可扩展的海量日志采集系统7.Hadoop应用架构8.HBase实战中文版9.Hive编程指南10.Kafka源码解析与实战11.Mahout算法解析与案例实战12.MapReduce设计模式[(美)迈纳,(美)舒克著]13.Scala编程中文版(33章全)14.Spark内核设计的艺术架构设计与实现(耿嘉安)15.Spark大数据分析核心概念技术及实践OCR16.Spark大数据处理:技术、应用与性能优化(全)17.Spark快速大数据分析18.Spark快速数据处理19.Spark机器学习20.Storm技术内幕与大数据实践21.图解Spark -核心技术与案例实战22.大数据Spark企业级实战版23.大数据架构师指南24.实战Elasticsearch、Logstash、Kibana:分布式大数据搜索与日志挖掘及可视25.机器学习与数据挖掘方法和应用(经典)26.深入理解Spark:核心思想与源码分析------Linux------1.Linux 内核设计与实现2.Linux内核设计与实现第3版_优先看3.Linux多线程服务端编程书签高清非扫描-陈硕4.linux常用命令大全Linux环境编程:从应用到内核5.Linux高性能服务器编程6.Linux高级程序设计中文第三版杨宗德--人电出版社7.UNIX 环境高级编程第3版8.Unix-Linux编程实践教程9.UNIX编程艺术-中文版【The+Art+of+UNIX+Programming】10.UNIX网络编程卷1 API UNIX网络编程卷2:进程间通信11.深入Linux内核架构(图灵程序设计丛书·LinuxUNIX系列)12.深入理解Linux内核13.鸟哥的Linux私房菜基础篇和服务器篇------python------1.Head_First_Python(中文版)2.Python Cookbook(第3版)中文版3.Python3程序开发指南Python参考手册(第4版)4.Python学习手册(第4版)5.Python开发技术详解6.Python核心编程第3版中文版7.Python正则表达式-深入浅出8.Python灰帽子——黑客与逆向工程师的Python编程之道9.Python编程入门经典10.Python编程初学者指南11.Python编程快速上手让繁琐工作自动化12.python编程金典13.Python高级编程14.编程小白的第一本python入门书------python数据分析和数据挖掘------1.Python数据分析基础2.Python数据挖掘入门与实践3.Python金融大数据分析4.Tableau:数据可视化之极速BI5.利用python进行数据分析6.数据可视化之美7.数据挖掘原理与算法8.数据挖掘导论-完整版9.用Python写网络爬虫10.精通Scrapy网络爬虫-刘硕------操作系统------pilers_ Principles, Techniques, and Toolsputer Systems_ A Programmer's Perspective3.分布式系统概念与设计原书第5版4.操作系统之哲学原理第2版5.操作系统概念-英文版6.操作系统概念7.操作系统概述-公众号资源8.操作系统真象还原9.操作系统精髓与设计原理第8版10.操作系统精髓与设计原理第9版11.操作系统设计与实现12.深入理解计算机系统第3版13.现代操作系统-英文版14.现代操作系统(第三版)中文版15.编译原理16.自己动手写操作系统17.计算机系统要素-从零开始构建现代计算机-----数据结构与算法------1.C++数据结构与算法(第4版)带书签目录完整版2.JavaScrit数据结构与算法(第2版)3.Java数据结构和算法4.严蔚敏:数据结构题集(C语言版)5.分布式算法导论6.剑指offer7.啊哈!算法哈磊8.大话数据结构9.妙趣横生的算法(C语言实现第2版)10.挑战程序设计竞赛(第2版)11.数据结构C语言严蔚敏pdf12.数据结构与算法Python语言描述_裘宗燕13.数据结构与算法分析C++描述14.数据结构与算法分析——Java语言描述15.数据结构与算法分析:C语言描述原书第2版高清版16.漫画算法:小灰的算法之旅17.程序员代码面试指南IT名企算法与数据结构题目最优解(左程云著)18.程序员的算法趣题19.算法(第4版)20.算法之道21.算法分析与设计22.算法图解23.算法竞赛入门经典训练指南24.算法谜题25.编程之美-完整版26.编程珠玑第二版人民邮电出版社27.背包九讲28.谷歌大佬总结的Leetcode刷题笔记,支持Java、C++、Go三种语言29.趣学算法------校招和面经------1.C++牛客大佬总结面试经验2.c++面经总结3.Java程序员面试宝典4.Java突击面试总结5.Java面试突击-V36.招聘笔记7.机器学习8.算法工程师带你去面试9.机器学习常见面试题10.牛客SQL练习题1-61答案与解析11.牛客网IT名企2016笔试真题+答案12.牛客网Java工程师校招面试题库13.程序员面试宝典14.阿里Java面试问题大全------计算机网络------puter Networking_ A Top-down Approachputer Networks, A Systems Approach3.HTTP权威指南4.Http核心总结5.TCP-IP详解卷1:协议原书第2版6.TCP-IP详解卷三7.TCP-IP详解卷二:实现8.tcp源码分析9.Wireshark 数据包分析实战(第二版)10.Wireshark网络分析就这么简单11.Wireshark网络分析的艺术12.图解HTTP13.图解TCPIP(第5版)14.网络是怎样连接的(图灵程序设计丛书)15.计算机网络第七版16.计算机网络-自顶向下方法-第6版17.计算机网络:系统方法18.计算机网络。
户外背包各部分的详细讲解

户外背包各部分的详细讲解无论你参加什么样的户外活动,身上总会背着一款适合运动的背包。
你对背包了解多少?你又如何选择合适的背包?下面谈谈户外背包各个部分的细节功能。
户外装备顾名思义是针对户外活动所设计、生产的装备。
不同户外活动方式有不同的针对性设计,清楚的了解你所进行的户外项目的特点和需要,是每个选择户外装备的朋友必须事前就要了解清楚的。
户外装备是经过特殊设计与生产工艺制作的。
它以应对恶劣的户外环境所生产的。
户外装备的特殊之处就是它独特制作工艺和设计,很多看似平凡的东西,其实初衷都是由众多使用者在无数次应用中得出的宝贵经验而来的。
这其中所包含的故事不一定是我们这些经常使用它们的人所能体会了解的。
作为户外装备,我们在户外活动中常用的背包算是我们接触最多的户外产品了.它们在具体的使用功能、制造工艺和材料上与我们平常生活中使用的运动背包有很大的不同。
随着设计理念和工艺水平的不断发展,当年清一色笨重的帆布军用背包早已变为各色背负、多种面料的专项用途产品。
在当前的户外市场上,背包是产品种类最多、针对性和功能性最全的产品。
在特点上它们有强调轻量化的、有强调结实耐用的;容积上的有小容量和大容量之分;功能上的有登山的、徒步的、攀冰的、探洞的,还有骑车用的等等。
现在的户外背包已经不简简单单是我们背负装备的工具,在特殊情况下它甚至可以变身为保暖的睡袋或是救死扶伤的担架。
户外产品的精髓就是满足人在户外活动中的需要。
而这种把需要转化为设计的工作正是生产厂商门孜孜不倦去追求的。
随着科技水平的不断发展,材料和制造工艺的日新月异,背包在细节的设计上被赋予了更多的功能。
厂家在有限的空间里,尽量从使用者的角度出发,对背包的细节进行了众多的处理。
使背包功能更加多用途化,让使用者的操作更加方便化。
我所跟大家谈的户外背包。
主要是针对大家经常使用的大容量背包为主。
从整体上看,这类背包可分为头包,背负,包体三部分。
那么我就根据自己接触过的背包产品,来按这三部分顺序来聊聊。
数模经验总结

下面总结一些小小的经验:1、组队很重要,队友们一定要能谈得来(曾经发生一组队员互相不服气,结果各自做各的,成绩就可想而知了),除此之外,队员之间一定要各有所常,建模嘛,无非就是查阅文献,建立模型,分析数据,编程,写文章,较对等等,保证你们组每个人都会有一些强项,当然男女生也应该都是要有的,所谓男女搭配,干活不累,嘿嘿;2、文章整洁很重要。
如果你是评委的话,肯定喜欢写的文章有条理,图文并茂之类的文章,将心比心,抓住评委的心才是最重要。
3、做建模创新很重要。
这么多的文章你的要想脱颖而出,创新也必须的,当然,你可以想你这篇文章结合了什么什么方法,最好把那方法说得天花乱坠,但不可华而不实,这就行啦。
4、摘要很重要。
以前大学生比赛的时候,是先通过摘要就刷一批,我觉得这是很公平的方法,摘要就是说明你这篇文章的特色和结构的,如果摘要我都不愿意看,干嘛花时间看你的正文。
5、人品很重要,还是我那句话,莫要太看重结果,抱着神马都是浮云的心态~~~数模经历入门篇平时有不少人会加我QQ,然后问诸如“什么是数模”“我该怎么学数模”之类的问题。
这里不是不鼓励大家和我讨论,而是有些问题google或baidu一下很容易得到答案,完全没有必要去问学长或老师。
而且使用搜索引擎的能力在数学建模中也是一个非常重要的能力。
这里推荐一些书,建议刚接触数学建模的朋友们看姜启源、谢金星的《数学模型》,这本书比较全面地介绍了数学建模中一些基本的、常用的模型和方法,有很多的例子,可以全面地了解什么是数学模型,也能基本地掌握如何抽象建模等。
希望进一步深入的同学推荐姜启源、谢金星的《数学模型案例集》,这本书里有不少比较有意思的问题,可以尝试自己做一下,难度比正式比赛要差很多,但是对于初学者来说比较容易上手。
也推荐叶其孝的那套黑书,虽然内容有点老,但是有很多比较有意思的解题思路等。
这里推荐一个很不错的数学建模网站:,那里有很多非常不错的学习资料。
对于那些已经有一些数学建模基础的同学则不推荐读叶其孝的那套书,而是可以直接在网上找一些往年国一或是美赛特等的文章,仔细阅读,了解其中的方法,然后自己动手重新做一遍。
背包商品说明书详解

背包商品说明书详解尊敬的用户,感谢您选择购买我们的背包商品。
为了让您更好地了解和使用我们的产品,我们特别编写了本商品说明书。
请仔细阅读以下内容,以便正确使用和享受我们的背包商品。
一、产品概述我们的背包商品是一款专为户外活动设计的多功能背包。
它采用优质尼龙材料制作,具备耐用、防水、抗撕裂等特点,适合于徒步旅行、露营、登山等户外运动。
二、产品特点1. 容量宽敞:背包内部设计了多个分隔式收纳空间,能够满足您对不同物品的分门别类装载需求。
此外,它还配备了多个外部网袋和挂钩,方便您携带水壶、登山杖、睡袋等物品。
2. 舒适背负:我们的背包采用了人体工程学设计,背负部分使用透气网布材料,给您提供良好的背部支撑和通风效果。
可调节的背带长度和腰带设计,能够按照个人需要进行自由调整,以提供更好的舒适性。
3. 强韧耐用:背包采用优质材料制作,经过严格的工艺处理,具备出色的耐磨和耐撕裂性能。
这使得背包能够在各种复杂环境下保持卓越的品质和寿命。
4. 多功能设计:我们的背包配备了多个细节设计,例如带防泼水拉链的主口袋,可以有效防止雨水渗入;胸部和腰部的调节扣,能够减轻肩膀和腰部的负担;还有独立的隔层,可用于存放笔记本电脑和其他贵重物品。
三、使用指南1. 调整背带:首先,根据个人身高和喜好,调整背带的长度,确保背包与身体相匹配。
然后,根据负重情况,适当调整腰带,使得重量合理分配在肩和腰部。
2. 装载物品:打开背包的主口袋,根据需求将物品放入相应的分隔空间中。
请注意,在装载贵重物品时,使用隔层,并小心放置,避免碰撞和损坏。
3. 防雨措施:如遇到雨天,可使用背包附带的防雨套,将整个背包完全包裹起来,确保物品的防水性能。
同时,请确保背包拉链完全封闭,以充分发挥雨水防护功能。
4. 清洁与维护:在使用完背包后,应及时清除内部和外部的污垢和杂物,并保持整洁干燥。
如遇到严重污渍,可使用温和的清洁剂进行清洁。
在不使用背包时,请将其存放在干燥通风的地方,避免阳光暴晒和潮湿环境。
noip复习资料(提高组c++版)
7.4多重背包问题79
7.5二维费用的背包问题80
7.6分组的背包问题81
7.7有依赖的背包问题81
7.8泛化物品81
7.9混合背包问题82
7.10特殊要求82
7.11背包问题的搜索解法83
7.12子集和问题84
第八单元 排序算法85
8.1常用排序算法85
8.2简单排序算法87
11.6进制转换(正整数)123
11.7高精度算法(压位存储)!123
11.8快速幂!128
11.9表达式求值129
11.10解线性方程组*133
第十二单元 数论算法135
12.1同余的性质!135
12.2最大公约数、最小公倍数!135
12.3解不定方程ax+by=c!*135
12.4同余问题*136
13.8拓扑排序152
13.9关键路径155
13.10二分图初步157
13.11小结160
第十四单元STL简介164
14.1STL概述164
14.2常用容器164
14.3容器适配器170
14.4常用算法171
14.5迭代器175
14.6示例:合并果子175
附录A思想和技巧177
A.1时间/空间权衡177
1.9简单的算法分析和优化14
1.10代码编辑器16
第二单元 基础算法17
2.1经典枚举问题17
2.2火柴棒等式18
2.3梵塔问题19
2.4斐波那契数列19
2.5常见的递推关系!20
2.6选择客栈22
2.72k进制数23
2.8Healthy Holsteins24
2.9小结25
acm中dp问题简单入门讲解
ACM暑期集训报告院系:专业:年级:学号:姓名:日期:西南交通大学目录目录.................................................. 错误!未定义书签。
第1章动态计划(dp) ............................ 错误!未定义书签。
简介.................................................... 错误!未定义书签。
教师内容................................................ 错误!未定义书签。
大体dp——背包问题..................................... 错误!未定义书签。
假设干经典dp及常见优化.................................. 错误!未定义书签。
类似题目................................................. 错误!未定义书签。
参考文献........................................... 错误!未定义书签。
附录1 暑期集训心得体会............................. 错误!未定义书签。
第1章动态计划(dp)(题目采纳2号黑体居中,下空1行)简介(题目采纳四号黑体,正文内容采纳小四号字体,倍行距)在解决问题的时候咱们常常碰到这种问题:在多种方式的操作下咱们如何取得一个最优的方式让咱们取得中意的结果。
这时咱们大多人的思想确实是贪婪。
不错贪婪确实是一个不错的算法,第一他简单容易想到,咱们在操作起来也比较容易。
此刻我推荐几道咱们oj上的贪婪算法的题:soj1562药品运输 soj1585 Climbing mountain。
为了引入动归算法我先拿药品运输这道题简单说一下贪婪算法。
例如1:药品运输(题目采纳小四号Times New Roman字体)Description大地震后,某灾区急需一批药品,此刻有N种药品需要运往灾区,而咱们的运输能力有限,此刻仅有M辆运输车用来运输这批药品,已知不同的药品对灾区具有不同的作用(“作用”用一个整数表示其大小),不同的药品需要的运输力(必要的车辆运载力)不同,而不同的车辆也具有不同的运输力。
登山背包功能详解
登山背包功能详解1 .登山包的结构及功能登山包结构可概括为三个部分——即背负系统、装载系统和外挂系统。
1.1 背负系统1.1.1 背负系统的设计原理背包设计来源于人体工程学,人类的脊椎由26块脊椎骨组成,并被我们分为5个区域。
从上向下1-7块为第一区;8-19为第二区;20-24为第三区;第25块为第四区;26块为第五区。
脊椎有以下四种主要功能:支持头部及躯干;保护脊椎的内部不受伤;支撑背部肌肉;使头部与躯干能够自由活动。
所以背包的背部设计必须完全符合人体脊椎的形状,这样才能减轻背包给人体带来的不舒适感,以及不妨碍头部及躯干的活动,并且将背包的重力更好地分散于背部各处。
同样,肌肉在背部的分布也是有一定的形状的。
所以背负设计必须符合人体肌肉的形状,通过将背负系统材料制成符合肌肉的形状,我们才可以将受力分散于整个背部,而不是集中于某一部分肌肉。
这种方法还减轻了肌肉的疲劳并使背包在身体上的稳定性增加了。
人的锁骨通常是突出的,所以背包背部的肩带必须依据锁骨的形状进行设计。
背包背部肩带必须依据肩甲骨进行设计,并充分考虑肩甲骨在运动中的自由度。
背包的腰带设计充分考虑了人体的胯骨形状,并且增加了背包的稳定性,能够随胯骨的运动而运动。
背包的背负系统的主导思想是将重量分散于整个背部,而不是集中于某一处,正是依据这一思想,形成了重量的传递的设计。
背包的腰带设计为圆锥型上斜式设计。
这种设计更加符合人体腰部曲线,并能将受力分散于腰的各个部位。
肩带肩部的受力是从背包的底部开始的,通过这样的设计,我们将重量分散于整个背部。
经常看到背着大包野营去的提法,其实准确说法应是驮着大包野营去,因为人在背包时,受力点在腰部,肩部只是辅助受力和控制平衡。
如果纯粹用肩部承受重量,一天下来,一定是肩酸腰疼,这样背包重力从肩到腰、从腰到腿的多环节力量传递,增加体力消耗是不难理解的。
而重心放在腰部,减少了承重受力的传递环节,也减少了不必要体力消耗。
动规-背包九讲完整版
为什么呢?可以这样理解:初始化的 f 数组事实上就是在没有任何物品可以放入背包时的合 法状态。如果要求背包恰好装满,那么此时只有容量为 0 的背包可能被价值为 0 的 nothing“恰好装满”,其它容量的背包均没有合法的解,属于未定义的状态,它们的值就都 应该是-∞了。如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不 装”,这个解的价值为 0,所以初始时状态的值也就全部为 0 了。
前言
本篇文章是我(dd_engi)正在进行中的一个雄心勃勃的写作计划的一部分,这个计划的内容是 写作一份较为完善的 NOIP 难度的动态规划总结,名为《解动态规划题的基本思考方式》。现 在你看到的是这个写作计划最先发布的一部分。
背包问题是一个经典的动态规划模型。它既简单形象容易理解,又在某种程度上能够揭示动 态规划的本质,故不少教材都把它作为动态规划部分的第一道例题,我也将它放在我的写作 计划的第一部分。
这个小技巧完全可以推广到其它类型的背包问题,后面也就不再对进行状态转移之前的初始 化进行讲解。
小结
01 背包问题是最基本的背包问题,它包含了背包问题中设计状态、方程的最基本思想,另 外,别的类型的背包问题往往也可以转换成 01 背包问题求解。故一定要仔细体会上面基本思 路的得出方法,状态转移方程的意义,以及最后怎样优化的空间复杂度。
感谢 XiaQ,它针对本文的第一个 beta 版发表了用词严厉的六条建议,虽然我只认同并采纳 了其中的两条。在所有读者几乎一边倒的赞扬将我包围的当时,你的贴子是我的一剂清醒 剂,让我能清醒起来并用更严厉的眼光审视自己的作品。
当然,还有用各种方式对我表示鼓励和支持的几乎无法计数的同学。不管是当面赞扬,或是 在论坛上回复我的贴子,不管是发来热情洋溢的邮件,或是在即时聊天的窗口里竖起大拇 指,你们的鼓励和支持是支撑我的写作计划的强大动力,也鞭策着我不断提高自身水平,谢 谢你们!
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
背包九讲P01: 01背包问题题目有N件物品和一个容量为V的背包。
第i件物品的费用是c[i],价值是w[i]。
求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
基本思路这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。
用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。
则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}。
这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。
所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。
如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”;如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f [i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。
注意f[i][v]有意义当且仅当存在一个前i件物品的子集,其费用总和为v。
所以按照这个方程递推完毕后,最终的答案并不一定是f[N] [V],而是f[N][0..V]的最大值。
如果将状态的定义中的“恰”字去掉,在转移方程中就要再加入一项f[i][v-1],这样就可以保证f[N] [V]就是最后的答案。
至于为什么这样就可以,由你自己来体会了。
优化空间复杂度以上方法的时间和空间复杂度均为O(N*V),其中时间复杂度基本已经不能再优化了,但空间复杂度却可以优化到O(V)。
先考虑上面讲的基本思路如何实现,肯定是有一个主循环i=1..N,每次算出来二维数组f[i][0..V]的所有值。
那么,如果只用一个数组f [0..V],能不能保证第i次循环结束后f[v]中表示的就是我们定义的状态f[i][v]呢?f[i][v]是由f[i-1][v]和f[i-1] [v-c[i]]两个子问题递推而来,能否保证在推f[i][v]时(也即在第i次主循环中推f[v]时)能够得到f[i-1][v]和f[i-1][v -c[i]]的值呢?事实上,这要求在每次主循环中我们以v=V..0的顺序推f[v],这样才能保证推f[v]时f[v-c[i]]保存的是状态f[i -1][v-c[i]]的值。
伪代码如下:for i=1..Nfor v=V..0f[v]=max{f[v],f[v-c[i]]+w[i]};其中的f[v]=max{f[v],f[v-c[i]]}一句恰就相当于我们的转移方程f[i][v]=max{f[i-1][v],f[i- 1][v-c[i]]},因为现在的f[v-c[i]]就相当于原来的f[i-1][v-c[i]]。
如果将v的循环顺序从上面的逆序改成顺序的话,那么则成了f[i][v]由f[i][v-c[i]]推知,与本题意不符,但它却是另一个重要的背包问题P02最简捷的解决方案,故学习只用一维数组解01背包问题是十分必要的。
总结01背包问题是最基本的背包问题,它包含了背包问题中设计状态、方程的最基本思想,另外,别的类型的背包问题往往也可以转换成01背包问题求解。
故一定要仔细体会上面基本思路的得出方法,状态转移方程的意义,以及最后怎样优化的空间复杂度。
P02: 完全背包问题题目有N种物品和一个容量为V的背包,每种物品都有无限件可用。
第i种物品的费用是c[i],价值是w[i]。
求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
基本思路这个问题非常类似于01背包问题,所不同的是每种物品有无限件。
也就是从每种物品的角度考虑,与它相关的策略已并非取或不取两种,而是有取0件、取1件、取2件……等很多种。
如果仍然按照解01背包时的思路,令f[i][v]表示前i 种物品恰放入一个容量为v的背包的最大权值。
仍然可以按照每种物品不同的策略写出状态转移方程,像这样:f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<= v}。
这跟01背包问题一样有O(N*V)个状态需要求解,但求解每个状态的时间则不是常数了,求解状态f[i][v]的时间是O(v/c[i]),总的复杂度是超过O(VN)的。
将01背包问题的基本思路加以改进,得到了这样一个清晰的方法。
这说明01背包问题的方程的确是很重要,可以推及其它类型的背包问题。
但我们还是试图改进这个复杂度。
一个简单有效的优化完全背包问题有一个很简单有效的优化,是这样的:若两件物品i、j满足c[i]<=c[j]且w[i]>=w[j],则将物品j去掉,不用考虑。
这个优化的正确性显然:任何情况下都可将价值小费用高得j换成物美价廉的i,得到至少不会更差的方案。
对于随机生成的数据,这个方法往往会大大减少物品的件数,从而加快速度。
然而这个并不能改善最坏情况的复杂度,因为有可能特别设计的数据可以一件物品也去不掉。
转化为01背包问题求解既然01背包问题是最基本的背包问题,那么我们可以考虑把完全背包问题转化为01背包问题来解。
最简单的想法是,考虑到第i种物品最多选V/c [i]件,于是可以把第i种物品转化为V/c[i]件费用及价值均不变的物品,然后求解这个01背包问题。
这样完全没有改进基本思路的时间复杂度,但这毕竟给了我们将完全背包问题转化为01背包问题的思路:将一种物品拆成多件物品。
更高效的转化方法是:把第i种物品拆成费用为c[i]*2^k、价值为w[i]*2^k的若干件物品,其中k满足c[i]*2^k<V。
这是二进制的思想,因为不管最优策略选几件第i种物品,总可以表示成若干个2^k件物品的和。
这样把每种物品拆成O(log(V/c[i]))件物品,是一个很大的改进。
但我们有更优的O(VN)的算法。
* O(VN)的算法这个算法使用一维数组,先看伪代码:<pre class"example"> for i=1..N for v=0..V f[v]=max{f[v],f[v-c[i]]+w[i]};你会发现,这个伪代码与P01的伪代码只有v的循环次序不同而已。
为什么这样一改就可行呢?首先想想为什么P01中要按照v=V..0的逆序来循环。
这是因为要保证第i次循环中的状态f[i][v]是由状态f[i-1][v-c[i]]递推而来。
换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品的子结果f[i-1][v-c[i]]。
而现在完全背包的特点恰是每种物品可选无限件,所以在考虑“加选一件第i种物品”这种策略时,却正需要一个可能已选入第i种物品的子结果f[i][v-c[i]],所以就可以并且必须采用v= 0..V的顺序循环。
这就是这个简单的程序为何成立的道理。
这个算法也可以以另外的思路得出。
例如,基本思路中的状态转移方程可以等价地变形成这种形式:f[i][v]=max{f[i-1][v],f[i][v-c[i]]+w[i]},将这个方程用一维数组实现,便得到了上面的伪代码。
总结完全背包问题也是一个相当基础的背包问题,它有两个状态转移方程,分别在“基本思路”以及“O(VN)的算法“的小节中给出。
希望你能够对这两个状态转移方程都仔细地体会,不仅记住,也要弄明白它们是怎么得出来的,最好能够自己想一种得到这些方程的方法。
事实上,对每一道动态规划题目都思考其方程的意义以及如何得来,是加深对动态规划的理解、提高动态规划功力的好方法。
P03: 多重背包问题题目有N种物品和一个容量为V的背包。
第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。
求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
基本算法这题目和完全背包问题很类似。
基本的方程只需将完全背包问题的方程略微一改即可,因为对于第i种物品有n[i]+1种策略:取0件,取1件……取n[i]件。
令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值,则:f[i][v]=max{f[i-1][v-k*c[i]]+ k*w[i]|0<=k<=n[i]}。
复杂度是O(V*∑n[i])。
转化为01背包问题另一种好想好写的基本方法是转化为01背包求解:把第i种物品换成n[i]件01背包中的物品,则得到了物品数为∑n[i]的01背包问题,直接求解,复杂度仍然是O(V*∑n[i])。
但是我们期望将它转化为01背包问题之后能够像完全背包一样降低复杂度。
仍然考虑二进制的思想,我们考虑把第i种物品换成若干件物品,使得原问题中第i种物品可取的每种策略——取0..n[i]件——均能等价于取若干件代换以后的物品。
另外,取超过n[i]件的策略必不能出现。
方法是:将第i种物品分成若干件物品,其中每件物品有一个系数,这件物品的费用和价值均是原来的费用和价值乘以这个系数。
使这些系数分别为1,2,4,...,2^(k-1),n[i]-2^k+1,且k是满足n[i]-2^k+1>0的最大整数。
例如,如果n[i]为13,就将这种物品分成系数分别为1,2,4,6的四件物品。
分成的这几件物品的系数和为n[i],表明不可能取多于n[i]件的第i种物品。
另外这种方法也能保证对于0..n[i]间的每一个整数,均可以用若干个系数的和表示,这个证明可以分0..2^k-1和2^k..n[i]两段来分别讨论得出,并不难,希望你自己思考尝试一下。
这样就将第i种物品分成了O(log n[i])种物品,将原问题转化为了复杂度为O(V*∑log n[i])的01背包问题,是很大的改进。
O(VN)的算法多重背包问题同样有O(VN)的算法。
这个算法基于基本算法的状态转移方程,但应用单调队列的方法使每个状态的值可以以均摊O(1)的时间求解。
由于用单调队列优化的DP已超出了NOIP的范围,故本文不再展开讲解。
我最初了解到这个方法是在楼天成的“男人八题”幻灯片上。
小结这里我们看到了将一个算法的复杂度由O(V*∑n[i])改进到O(V*∑log n[i])的过程,还知道了存在应用超出NOIP范围的知识的O(VN)算法。
希望你特别注意“拆分物品”的思想和方法,自己证明一下它的正确性,并用尽量简洁的程序来实现。
P04: 混合三种背包问题问题如果将P01、P02、P03混合起来。
也就是说,有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。
应该怎么求解呢?01背包与完全背包的混合考虑到在P01和P02中最后给出的伪代码只有一处不同,故如果只有两类物品:一类物品只能取一次,另一类物品可以取无限次,那么只需在对每个物品应用转移方程时,根据物品的类别选用顺序或逆序的循环即可,复杂度是O(VN)。