背包九讲完整版_背包九讲

合集下载

(第九讲)哥廷根

(第九讲)哥廷根

哥廷根哥廷根(Gottingen 、G öttingen),又译格廷根(G öttingen),是个德国下萨克森州(Niedersachsen)的城市。

其为哥廷根区的首府。

莱茵河支流的支流莱讷河流过此城。

人口:13万;面积:117.27 平方公里;时区:+01:00.。

德国的心脏哥廷根(G öttingen ),这座总人口不过13万人的小城,却有四十多位诺贝尔奖得主或在此读过书或在此教过学,使其在历史上当之无愧成为德国的学术之都,世界的科学中心。

这是被誉为国宝的季羡林先生从学生转变成大师的地方,他在此居住过10年的地方其实就是一个普通的三层小楼,当年和广大留学生一样仅租住在三层的某间。

这个楼年代较近,不像其他建筑比较古老,看着这栋几经易主的建筑,当年年轻的季羡林在三层阁楼伏案研修梵文、吐火罗文……,其实季先生在此和德国美女伊姆加德还有过一段令人扼腕的爱情故事,伊姆加德60年隔空守候的坚韧实在令人涕下。

季老已于几年前辞世,不知道伊姆加德是否也已离开人世……该市以哥廷根大学闻名。

是世界闻名的花国,中国著名学家季羡林在1935年9月被哥廷根大学录取并在此求学。

季羡林故居(第二个拱形门三层某间)从哥廷根到普林斯顿20世纪初,全世界数学系的学生都会受到同样的忠告:“打起你的背包,到哥廷根去!”哥廷根是德国汉诺威市以南65千米的一座小城,1734年在此设立大学。

哥廷根的伟大科学传统,为数学王子高斯所创。

高斯于1795年第一次来到哥廷根,第二次再来哥廷根时,他已是天文台台长,兼任教授,此后在那里度过了余生,在纯粹数学和应用数学各个方面做出了贡献。

19世纪末,德国数学飞速发展,柏林大学是数学中心,当时的哥廷根并不突出。

1872年,克莱因发表“埃尔朗根纲领”,使其名声大振。

1886年克莱因来到哥廷根担任数学教授,当时哥廷根大学在编的数学教授只有两名,另一名是韦伯。

克莱因来到哥廷根后,主要负责行政组织、数学教育、国际交流等活动。

acm中d问题简单入门讲解

acm中d问题简单入门讲解

ACM暑期集训报告院系:专业:年级:学号:姓名:日期:西南交通大学目录目录 (1)第1章动态规划(dp) (2)1.1 简介 (2)1.2 教师内容 (5)1.3 基本dp——背包问题 (6)1.4若干经典dp及常见优化 (9)1.5类似题目 (10)参考文献 (31)附录1 暑期集训心得体会 (31)第1章动态规划(dp)(标题采用2号黑体居中,下空1行)1.1 简介(标题采用四号黑体,正文内容采用小四号字体,1.5倍行距)在解决问题的时候我们经常遇到这种问题:在多种方式的操作下我们如何得到一个最优的方式让我们得到满意的结果。

这时候我们大多人的思想就是贪心。

不错贪心确实是一个不错的算法,首先他简单容易想到,我们在操作起来也比较容易。

现在我推荐几道我们oj上的贪心算法的题:soj1562药品运输soj1585 Climbing mountain。

为了引入动归算法我先拿药品运输这道题简单说一下贪心算法。

示例1:药品运输(题目采用小四号Times New Roman字体)Description5.12大地震后,某灾区急需一批药品,现在有N种药品需要运往灾区,而我们的运输能力有限,现在仅有M辆运输车用来运输这批药品,已知不同的药品对灾区具有不同的作用(“作用”用一个整数表示其大小),不同的药品需要的运输力(必要的车辆运载力)不同,而不同的车辆也具有不同的运输力。

同时,我们希望不同的药品用不同的车辆来运输(避免发生混淆)。

现在请你帮忙设计一方案,来使得运往灾区的药品对灾区的作用最大。

Input第一行包含一个整数T,表示需要处理的测试数据组数。

每一组第一行包括两个整数N,M,分别表示药品总数,及车辆总数。

接着第二行包含N个整数(pi<=10000),分别表示每种药品的作用。

接着第三行包含N个整数,分别表示每种药品必须得运载力(wi<=1000)。

接着第四行包含M个整数,表示每辆车的运输力(c<=1000);(T<=10; N,M<=1000)Output输出包括T行,每行仅一个整数,表示最大的作用值。

胡孚琛丹道法诀十二讲

胡孚琛丹道法诀十二讲

胡孚琛丹道法诀十二讲
胡孚琛:丹道法诀十二讲
胡孚琛:丹道法诀十二讲(揭秘丹学和密宗修持法诀)序
【上卷】


1



讲 (73)
辟谷胎息第五讲 (85)
第一节辟谷简论 (87)
第二节胎息概说 (91)
行功语要第六讲 (97)
第一节丹道行功的姿势 (98)
第二节建筑心灵堤防 (103)
第三节虚寂恒诚及“忘”字诀 (106)

第五节

第二节闭固之法 (158)
第三节男女相恋之真谛 (161)
第四节肉体返还之功 (171)
开悟禅定第九讲 (179)
第一节禅法略论 (182)
第二节何谓开悟 (187)
第三节何谓禅定 (196)
第四节入定的证量 (205)
第五节开发灵性思维 (212)


第二章丹道之修真辨难和答疑 (296)
第一节三家四派丹法之区别和联系 (296)
第二节丹道对灵界的设定 (303)
第三节积德通灵,集义生气,唯道集虚 (315)
第四节丹道形、气、神之修炼要义 (329)
第五节丹道铸剑功略说 (336)
第六节为学与为道 (350)
第三章丹道筑基功 (384)
第一节无食、无念、无息 (386)
第二节填髓法和抗寒功 (392)

第七节人是文化的载体 (451)
第八节人是形、气、神的三重结构体 (463)
第二章人的基本生命活动 (471)
第一节生与死 (472)
第二节病与老 (517)
第三节过激行为 (564)
第四节性活动 (572)。

dp入门

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]; }

Osprey Sojourn系列背包使用说明书

Osprey Sojourn系列背包使用说明书

SOJOURN SERIESSOJOURN 80L/28"SOJOURN 60L/25"SOJOURN 45L/22"Welcome to Osprey. We pride ourselves on creating the most functional,durable and innovative carrying product for your adventures. Please refer tothis owner’s manual for information on product features, use, maintenance, customer service and warranty.OWNER'S MANUALFEATURES1 Z ippered top pocket provides easy access to toiletries and liquids2 Padded top and side handles provide comfortable carry3 D ual tube extended handle for control of large loads on rough surfaces4 Large panel zip with lockable sliders access the main compartment5 Rear panel pocket and ID card window with removable shoulder harness6 D ual front panel daisy chains for additional gear attachment7 Lightweight, high-rolling clearance HighRoad™ Chassis8 Long haul capable deployable harness, hipbelt and backpanel9Removable suspension components for increased packing capacity10 D ual StraightJacket™ compression straps to secure contents+ I nternal compression straps with fabric wings hold clothes securely + F our zippered pockets in main compartment keep gear organized FABRICMAIN 420 Nylon Shadow Box ACCENT 1680D Ballistic Nylon BOTTOM 900D Super Oxford1 410 710632285899SOJOURN 80L/28" SPECS ONE SIZECubic Inches 4882Liters 80Pounds 8.97 Kilograms 4.07Inches 28h x 14w x 14d Centimeters 71h x 36w x 35dSOJOURN 60L/25" SPECS ONE SIZECubic Inches 3661Liters 60Pounds 8.53 Kilograms 3.87Inches 25h x 14w x 14d Centimeters 64h x 36w x 35dSOJOURN 45L/22" SPECS ONE SIZECubic Inches 2746Liters 45Pounds 7.93 Kilograms 3.60Inches 22h x 14w x 9d Centimeters 56h x 36w x 23dSUSPENSION1 HIGHROAD ™ SUSPENSION+ A lloy peripheral frame and center handle stays2S TOWAWAY TENSIONED BACKPANEL +A nti-Gravity TM inspired tension lumbar surface + Tensioned air mesh-covered backpanel+ Dual position extended adjustable torso**Single position on 22"3 STOWAWAY VENTILATED HARNESS + V entilated mesh-covered die-cut foam harness+ Comfortable, ventilated air mesh-covered contact surfaces+ Adjustable sternum strap with whistle4S TOWAWAY PADDED HIPBELT + Padded air mesh-covered hipbelt+ S ingle 25 mm webbing ErgoPull™ closure231SIZING / FITHARNESS FITThe harness straps should wrap fully around your shoulders with no gaps between the pack and your back. The padded part of the harness straps should end 1"/2.5 cm- 2"/5 cm below the armpits and the sternum strap adjusted to approximately 2"/5 cm below the collarbone.4TOP LIQUIDS POCKET80L / 60L / 45LThe liquids pocket is located at the top of the luggage piece and provides quick and easy zip access to a toiletry kit or other small items. Its bellowed design collapses to ensure the full main compartment volume is available for gear and clothing. It is conveniently sized to fit a variety of 1L/1 qt wash bags or Osprey'sAirporter travel duffel and cover.TOP AND SIDE LOW PROFILE CARRY HANDLES 80L / 60L / 45LTwo padded low profile handles provide an easy option to grab, pull and maneuver your bag. Heavy duty fabric on the outside protects the handles,and soft padded material underneath are comfortable and easy to use. A third handle is molded into the front of the HighRoad™ Chassis and serves as both a handle and front bumper.LARGE ACCESS MAIN COMPARTMENT80L / 60L / 45LA full front panel U-zip opening provides large access to gear, and a stiffened zipper path provides structure to keep the main compartment open while packing or unpacking. Bright internal liner materials make it easy to find both small and large items stored within. For additional organization, the mesh and solid side pockets provide convenient and private storage.INTERNAL COMPRESSION STRAPS 80L / 60L / 45LUse the internal compression straps to maximize packing space, organize and stabilize loads inside the main compartment. Unbuckle and loosen the straps before packing and hang the straps on the outside of either side of the pack. After packing, buckle the straps and cinch them evenly so that the buckle remains in the middle of the pack.DUAL FRONT DAISY CHAINS 80L / 60L / 45LDaisy chains provide multiple attachment points foradditional straps, attaching external gear and accessories.STRAIGHTJACKET TM COMPRESSION SYSTEM 80L / 60L / 45LOsprey's StraightJacket™ compression system secures loads and adds stability. External compression straps and padded side walls wrap and protect the internal contents of the pack.A W hen the pack is full, attach the compression straps to the buckles atthe front edge of the padded side wall.B W hen packing smaller loads, attach the compression straps to thehidden buckles along the right side of the pack, near the backpanel.C C inch down the padded side walls.CONVERTIBLE BACKPACK-STYLE CARRY80L / 60L / 45LThe suspension on the Sojourn High Road™ Chassis provides a comfortable backpack-style carry.TO DEPLOY THE HARNESS AND HIPBELT A Unzip the rear flap.B Remove the hipbelt and harness from behind the backpanel.C Tuck flap into the space behind the hipbelt to secure it away.D A ttach the hipbelt to the two buckles located on the bottom of the bag.Attach the harness straps to the buckles on the side of the hipbelt.E Reverse the steps to stowaway the backpanel.TO REMOVE THE HARNESS AND HIPBELT A Unzip the rear flap.B Remove the hipbelt from behind the backpanel.C Unclip the buckles located at the top of the harness straps.D S lide your hand between the harness and backpanel to breakthe hook and loop closure and remove the harness.E Reverse the steps to reinstall the harness and hipbelt.LOCKABLE SLIDERS ON MAIN COMPARTMENT ZIPPER 80L / 60L / 45LThe main compartment features lockable zippers to secure your bag's contents. We recommend using TSA-approved locks.HIGHROAD™ CHASSIS 80L / 60L / 45LAll Osprey wheeled travel packs utilizeOsprey’s proprietary High Road™ Chassis. It features: A A n ergonomic retractablehandle with integrated vent fins B 6061 T6 aluminum frame C U ltra-durable and lightweight compositebase with a fiberglass matrix inlay and integrated foot/grab handle D O versized, high traction polyurethanewheels with sealed bearings and a high clearance design.DAYLITE COMPATIBLE 80L / 60L / 45LAll Sojourn Series packs are compatible with our Daylite daypack. Attach the Daylite using the four D-rings on the front of the pack.For more information on this product and others, pack care, how to pack your pack,our lifetime guarantee, or to contact Osprey Customer Service, visit .OWNER'S MANUAL。

吕伟聪-捉羊计划

吕伟聪-捉羊计划

p[x]
p[x]
x A B A
x B
以把一个机器人的移动路线改为 p[x]→x→A→x→B→x→p[x],另一个机器人则是停在 p[x], 效果相同,但(p[x], x)这条边可以少走两次,于是我们就得到了一个更优的方案。经过这个 转化后,可以发现算法一中的 f[x][i][j]和 g[n][i][j]都只需要计算满足 0≤j≤1 的状态。 于是,这个算法的空间复杂度降到了 O(2NK)=O(NK)。在计算 g[n][i][j]时需要枚举 i0、 j0、jn(in 可以直接计算出来) ,所以转移的时间为 O(4K),而状态数为 O(2NK),所以每做一 次动态规划的时间复杂度为 O(8NK2),总的时间复杂度为 O(8N2K2)=O(N2K2)。这个算法的常 数是比较大的,期望得分为 35 分。 【算法三】 如果要枚举根的话,算法二达到的 O(N2K2)的时间复杂度已经很难再降低了,只是过大 的常数影响了算法的效率。这里考虑有没有常数较小的算法也能达到这个时间复杂度。 观察算法一原始的状态转移方程:
g[n][i][ j] min{ f [ x1 ][i1 ][ j1 ] f [ x2 ][i2 ][ j2 ] …… f [ xn ][in ][ jn ]}
其中 jk≤ik≤i, i i1 j1 i2 j2 …… in jn j 。不难发现这个式子和前面的式子 很像,因为这就是利用 g 来存储中间结果以避免重复计算。状态转移方程为
i j (i1 j1 ) (i2 j2 ) …… (im jm )
这启 ik jk 代表了什么呢?不难发现就是最后停在以 xk 为根的子树中的机器人的个数。 发我们从“最后每棵子树内停了多少个机器人”入手。 在对一些例子进行分析之后,可以发现另一个性质:在最优方案中,如果有至少 2 个机 器人进入了以 x 为根的子树,那么这些机器人都应该停在以 x 为根的子树内。证明如下:

神农架国家森林公园总体规划

神农架国家森林公园总体规划

13 ................................................................................................................. )STAERHT(胁威 节四第
章 五第
52 ................................................................................................................. 测预场市源客 节二第 91 ........................................................................................................ 析分状现场市源客 节一第 91 ...................................................................................................... 测预与析分场市源客
章 十第
37 ................................................................................................................. 划规护救疗医 节七第 17 ................................................................................................................. 划规统系识标 节六第 17 ................................................................................................................. 划规厕公游旅 节五第 07 ................................................................................................................. 划规施设饮餐 节四第 96 .......................................................................................... 划规施设区务服待接游旅 节二第 96 ........................................................................................................ 划规门大园公林森 节一第 96 ...........................................................................................................划规施设务服游旅 07 ................................................................................................................. 划规施设宿住 节三第

动规-背包九讲完整版

动规-背包九讲完整版
如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该将 f[0..V]全部设 为 0。
为什么呢?可以这样理解:初始化的 f 数组事实上就是在没有任何物品可以放入背包时的合 法状态。如果要求背包恰好装满,那么此时只有容量为 0 的背包可能被价值为 0 的 nothing“恰好装满”,其它容量的背包均没有合法的解,属于未定义的状态,它们的值就都 应该是-∞了。如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不 装”,这个解的价值为 0,所以初始时状态的值也就全部为 0 了。
前言
本篇文章是我(dd_engi)正在进行中的一个雄心勃勃的写作计划的一部分,这个计划的内容是 写作一份较为完善的 NOIP 难度的动态规划总结,名为《解动态规划题的基本思考方式》。现 在你看到的是这个写作计划最先发布的一部分。
背包问题是一个经典的动态规划模型。它既简单形象容易理解,又在某种程度上能够揭示动 态规划的本质,故不少教材都把它作为动态规划部分的第一道例题,我也将它放在我的写作 计划的第一部分。
这个小技巧完全可以推广到其它类型的背包问题,后面也就不再对进行状态转移之前的初始 化进行讲解。
小结
01 背包问题是最基本的背包问题,它包含了背包问题中设计状态、方程的最基本思想,另 外,别的类型的背包问题往往也可以转换成 01 背包问题求解。故一定要仔细体会上面基本思 路的得出方法,状态转移方程的意义,以及最后怎样优化的空间复杂度。
感谢 XiaQ,它针对本文的第一个 beta 版发表了用词严厉的六条建议,虽然我只认同并采纳 了其中的两条。在所有读者几乎一边倒的赞扬将我包围的当时,你的贴子是我的一剂清醒 剂,让我能清醒起来并用更严厉的眼光审视自己的作品。
当然,还有用各种方式对我表示鼓励和支持的几乎无法计数的同学。不管是当面赞扬,或是 在论坛上回复我的贴子,不管是发来热情洋溢的邮件,或是在即时聊天的窗口里竖起大拇 指,你们的鼓励和支持是支撑我的写作计划的强大动力,也鞭策着我不断提高自身水平,谢 谢你们!

背包问题之零一背包

背包问题之零一背包

背包问题之零⼀背包注:参考⽂献《背包九讲》.零⼀背包问题⼀:题⽬描述 有 N 件物品和⼀个容量为 V 的背包.放⼊第 i 件物品耗⽤的费⽤为C i(即所占⽤背包的体积),得到的价值是 W i.求将哪些物品装⼊背包所得到的总价值最⼤.⼆:基本思路 01背包是最基础的背包问题,这道题的特点是每种物品仅有⼀件,可以选择放或不放,且不要求背包必须被放满,只要求最后的总价值最⼤. ⽤⼦问题定义状态:F[i][v] 表⽰对于前 i 件物品,当背包容量为 v 时所能得到的价值最⼤值.设想,将 "前 i 件物品放⼊容量为 v 的背包中" 这个⼦问题,若只考虑第 i 件物品的策略(要么放要么不放),那么就可以转化为⼀个之和前 i - 1 件物品相关的问题.如果不放第 i 件物品, 那么问题就转化为 ”前 i - 1 件物品放⼊容量为 v 的背包中“,价值就是 F[i - 1][v]; 如果放第 i 件物品,那么问题就转化为 ”前 i - 1 件物品放⼊剩下的容量为v - C i的背包中”, 此时获得的价值为 F[i - 1][v - C i] + W i。

特殊的,当 v < C i时,可以认为当前的容量是放不下第 i 件物品的,即此时相当于不放第 i 件物品的价值F[i - 1][v].分析到这⾥则可得状态转移⽅程为: F[i][v] = v < C i F[i - 1][v] : max( F[i - 1][v], F[i - 1][v - C i] + W i ).在这⾥要特别的说明⼀下,这个⽅程⾮常重要,⼀定要知道这是怎么推出来的,⼏乎后⾯的所有的背包问题都和这个⽅程有着密不可分的联系.伪代码如下:F[0...N][0...V] <--- 0for i <--- 1 to N for v <--- C i to V F[i][v] = v < C i F[i - 1][v] : max( F[i - 1][v], F[i - 1][v - C i] + W i );具体代码:1void _01Pack(int F[][MAXV], int N, int V, int C[], int W[]){2 memset(F, 0, sizeof(F));3for(int i = 1; i <= N; i++) {4for(int v = 0; v <= V; v++) {5 F[i][v] = v < C[i] ? F[i - 1][v] : max(F[i - 1][v], F[i - 1][v - C[i]] + W[i]); //放或者不放两者之中选择最优者6 }7 }8 }三:优化空间复杂度 可以清楚的看到上⾯算法的时间复杂度和空间复杂度均为 O(N * V), 这⾥时间复杂度已经不能得到优化,但是空间复杂度确可以优化到O(V). 先看上⾯代码是如何实现的.最外⾯⼀层循环,每次计算出⼆维数组 F[i][0...V] 的值,计算的时候 F[i][0...V] 是由它的上⼀层 F[i - 1][0...V] ⽽得到的.那么如果把这个数组换成⼀维的 F[v] 那么还能保留上⼀次的状态吗.答案是可以的.由于动态规划算法的⽆后效性,第 i + 1 件物品的选择与否不会影响到第 i 件物品(即它的前⼀件物品)的选择状态.那么可以在上⾯第⼆次循环中按照 v <--- V...0 递减的顺序来计算 F[v], 这样计算F[v] 时所需要的状态 F[v] 和 F[v - C i] + W i 仍然还是上⼀次的状态.⽽计算 F[v] 之后, v 的顺序是递减的, F[v] 不会影响到 F[v'] (v' < v), 因为F[v']只与 F[v'](上⼀次的值) 和 F[v - C i] 有关, ⽽ F[v] > F[v'] > F[v' - C i]. 所以⼜可得状态转移⽅程. F[v] = max( F[v], F[v - C i] + W i ).伪代码如下:F[0...V] <--- 0for i <--- 1 to N for v <--- V to C i F[v] = max( F[v], F[v - C i] + W i );具体代码:1void _01Pack(int F[], int N, int V, int C[], int W[]){2 memset(F, 0, sizeof(F));3for(int i = 1; i <= N; i++) {4for(int v = V; v >= C[i]; v--) {5 F[i][v] = max(F[v], F[v - C[i]] + W[i]);6 }7 }8 }可以看到从第⼀个状态转移⽅程到第⼆个状态转移⽅程的空间优化效率还是挺⼤的: F[i][v] = max( F[i - 1][v], F[i - 1][v - C i] + W i ). ----> F[v] = max( F[v], F[v - C i] + W i ).在第⼆个⽅程中 F[v]1 = max(F[v]2, F[v - C i] + W i), 其实 F[v]2 就相当与⽅程⼀中的 F[i - 1][v], 对应的 F[v - C i] + W i就相当于 F[i -1][v - C i] + W i.这⼀正确性是在内层循环递减的前提下才成⽴的.否则, 将内层循环改为递增, 那么 F[i][v] 其实是由 F[i][v] 和 F[i][v - C i] 推出来的,这不符合基本思路中的探讨.之前说过由于 01背包的特殊性,这⾥将 01背包抽象化,⽅便之后的调⽤.解决单个物品 01背包的伪代码:def ZeroOnePack (F, C, W) for v <--- V to C F[v] = max( F[v], F[v - C] + W );这么写之后, 01背包总问题解决的伪代码就可以改写成:F[0...V] <--- 0for i <--- 1 to N ZeroOnePack(F, C[i], W[i]);具体代码:1const int MAXN = 10000;2int N, V, C[MAXN], W[MAXN];34void ZeroOnePack(int F[], int C, int W) { // 对于单个物品的决策5for(int v = V; v >= C; v--) {6 F[v] = max(F[v], F[v- C] + W);7 }8 }910void solv(int F[]) {11 memset(F, 0, sizeof(F));12for(int i = 1; i <= V; i++) {13 ZeroOnePack(F, C[i], W[i]);14 }15 }四: 01背包问题的拓展 ------ 初始化的细节问题 在上述 01背包的问题中,仅问得是 “如何选取,才能使的最后的总价值最⼤”, 这⾥并没有规定是否必须装满背包, 但是有的题将会给予这个附加条件, 即“在要求恰好装满背包的前提下, 如何选取物品, 才能使的最后的总价值最⼤ ”. 这两种问法, 在代码实现上相差⽆⼏.如果是上述问法,要求 “恰好装满背包”, 那么在初始化时除了将 F[0] 赋值为 0 之外, 其他的 F[1...V] 都应该赋值为 -∞,这样就可以保证最后的得到的 F[V] 是⼀种恰好装满背包的最优解.如果没有要求必须把背包装满,⽽是只希望价值尽量最⼤,初始化时应该将F[0...V] 全部设置为 0. 之所以可以这么做,是因为初始化的 F[] 事实就是没有任何物品放⼊背包时的合法状态.如果要求背包恰好装满,那么只有容量为 0 的背包在什么也不装且价值为 0 的情况下被装 "恰好装满",其他容量的背包如果不装物品, 那么默认的情况下都是不合法状态,应该被赋值为 -∞, 即对于第⼀个物品⽽⾔, 其合法状态只能由 F[0] 转移得到.如果背包并⾮必须被装满,那么任何容量的背包在没有物品可装时都存在⼀个合法解,即什么都不装,且这个解的价值为 0.所以将其全部初始化为 0 是可以的. 注:这个技巧完全可以拓展到其他背包问题中.伪代码:def ZeroOnePack (F, C, W) for v <--- V to C F[v] = max( F[v], F[v - C] + W )end defdef slov() F[0] = 0, F[1...V] <--- -∞ for i <--- 1 to N ZeroOnePack(F, C[i], W[i])end def具体代码:1const int MAXN = 10000;2int N, V, C[MAXN], W[MAXN];34void ZeroOnePack(int F[], int C, int W) {5for(int v = V; v >= C; v--) {6 F[v] = max(F[v], F[v- C] + W);7 }8 }910void solv(int F[]) {11 F[0] = 0;12for(int i = 1; i <= V; i++) F[i] = INT_MIN; // 除F[0] = 0之外, 其他全部赋值为负⽆穷13for(int i = 1; i <= V; i++) {14 ZeroOnePack(F, C[i], W[i]);15 }16 }五:⼀个常数级别的优化上述伪代码的:for i <--- 1 to N for v <--- V to C i可以优化为:for i <--- 1 to N for v <--- V to max( V - SUM(i...N)C i, C i)。

NOIP复习资料(C++版)精编版

NOIP复习资料(C++版)精编版

NOIP复习资料(C++版)主编葫芦岛市一高中李思洋完成日期2012年8月27日……………………………………………………………最新资料推荐…………………………………………………前言有一天,我整理了NOIP的笔记,并收集了一些经典算法。

不过我感觉到笔记比较凌乱,并且有很多需要修改和补充的内容,于是我又搜集一些资料,包括一些经典习题,在几个月的时间内编写出了《NOIP复习资料》。

由于急于在假期之前打印出来并分发给同校同学(我们学校既没有竞赛班,又没有懂竞赛的老师。

我们大家都是自学党),《NOIP复习资料》有很多的错误,还有一些想收录而未收录的内容。

在“减负”的背景下,暑期放了四十多天的假。

于是我又有机会认真地修订《NOIP复习资料》。

我编写资料的目的有两个:总结我学过(包括没学会)的算法、数据结构等知识;与同学共享NOIP知识,同时使我和大家的RP++。

大家要清醒地认识到,《NOIP复习资料》页数多,是因为程序代码占了很大篇幅。

这里的内容只是信息学的皮毛。

对于我们来说,未来学习的路还很漫长。

基本假设作为自学党,大家应该具有以下知识和能力:①能够熟练地运用C++语言编写程序(或熟练地把C++语言“翻译”成Pascal语言);②能够阅读代码,理解代码含义,并尝试运用;③对各种算法和数据结构有一定了解,熟悉相关的概念;④学习了高中数学的算法、数列、计数原理,对初等数论有一些了解;⑤有较强的自学能力。

代码约定N、M、MAX、INF是事先定义好的常数(不会在代码中再次定义,除非代码是完整的程序)。

N、M、MAX 针对数据规模而言,比实际最大数据规模大;INF针对取值而言,是一个非常大,但又与int的最大值有一定差距的数,如100000000。

对于不同程序,数组下标的下限也是不同的,有的程序是0,有的程序是1。

阅读程序时要注意。

阅读顺序和方法没听说过NOIP,或对NOIP不甚了解的同学,应该先阅读附录E,以加强对竞赛的了解。

NOIP的DP总结之DP类型

NOIP的DP总结之DP类型
代码:
procedure MultiplePack(cost,weight,amount)
if cost*amount>=V
CompletePack(cost,weight)
return
integer k=1
while k<amount
ZeroOnePack(k*cost,k*weight)
amount=amount-k
f[j*v+k]:=b[l]+j*w; //用队列头的值更新f[j*v+k]
end;
end;
end;
writeln(f[m]);
end.
题目:砝码秤重,tyvj1086,zoj2156,poj2392,hdu1085
Poj1014,divide(见dp2)
二维费用背包
就是限制条件多了一个,变成了二维容量,从而状态多了一维而已。
题目:hdu3236,打包(见dpset)poj2184
分组背包
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是一件都不选。也就是说设f[k][v]表示前k组物品花费费用v能取得的最大权值,则有:f[k][v]
for i:=1 to n do
begin
read(v,w,c); //读入当前物品:v为物品体积、w为物品价值、c为物品可用次数
if m div v<c k:=0 to v-1 do //把所有的体积按除以v的余数划分为0~v-1

背包九讲

背包九讲
背包
By @wgx998877
九 讲
Copy right@中国地质大学(北京)ACM/ICPC 集训队
背包问题及其变化
完全背包
01背包 ZeroOnePack
CompletePack
混合背包 MixedPack
MultiplePack
多重背包
二维费用背包 泛化物品 有依赖背包 分组背包
有N件物品和一个容量为V的背包。第i件物 品的费用是c[i],价值是w[i]。求解将哪些物 品装入背包可使价值总和最大。
void OneZeroPack(int cost,int value){ int i,j; for(i = total;i >= cost; i--) f[i] = max(f[i],f[i-cost]+value); }
逆序! 这就是关键! 1 for i=1..N 2 for v=V..0 3 f[v]=max {f[v],f[v-c[i]]+w[i]}; 4 分析上面的代码:当内循环是逆序时 就可以保证后一个f[v]和f[v-c[i]]+w[i]是前一状态的! 这里给大家一组测试数据: 测试数据: 10,3 3,4 4,5 5,6
二维费用背包
有依赖背包
分组背包
for i=1..N if //第i件物品属于01背包 ZeroOnePack(c[i],w[i]) else if //第i件物品属于完全背包 CompletePack(c[i],w[i]) else if //第i件物品属于多重背包 MultiplePack(c[i],w[i],n[i])
混合背包 MixedPack
MultiplePack
多重背包
for (i = 1; i < N; ++i) { if (cost[i] * amount[i] >= V) { CompletePack(cost[i], weight[i]); return; } int k = 1; while (k < amount[i]) { ZeroOnePack(k*cost[i], k*weight[i]); amount[i] = amount[i] - k; k = k*2; } ZeroOnePack(amount[i]*cost[i], amount[i]*weight[i]); }

军训教程指令【给大学新上任的体委】

军训教程指令【给大学新上任的体委】

新生入学军事训练教程/新/生/入/学/军/事/训/练/组/织/与/实/施/程/序第一部分:队列训练/目录(理论部分)第一讲/队列训练组织与指挥单个军人队列动作:第二讲/立正、跨立、稍息/第三讲/停止间转法/第四讲/坐下、蹲下、起立/第五讲/脱帽、戴帽、整理着装/第六讲/敬礼、礼毕/第七讲/齐步与立定/第八讲/正步与立定/第九讲/跑步与立定/第十讲/便步、踏步、移步/第十一讲/步法变换/第十二讲/行进间转法/第十三讲/操枪分队、部队动作:第十四讲/班的队列动作/第十五讲/排的队列动作/第十六讲/连的队列动作第十七讲/轻武器射击/第一讲/队列训练组织与指挥(理论讲解)教学提要/目的:使同志们知道队列训练的基本内容、术语、实施程序、方法和下达口令的时机,明确军人在队列训练中的基本要求、意义和作用,为建立正规的队列训练奠定基础。

内容:一、队列训练总的方法二、《队列条令》的基本内容三、队列术语、要求和纪律/方法:讲解示范、阅读条令、讨论、作业时间;4课时/地点:教室/要求:认真听讲,仔细琢磨,做好笔记,完成作业。

/教学保障:《队列条令》和《队列条令》学习辅导材料、教案/教学进程授课准备:1/清点人数2/宣读教学提要理论讲解:(2课时)今天我们一起来学习《队列条令》,通过本课学习,目的是为队列训练打下坚实的理论基础。

一、//队列训练总的方法,即七步训练法第一步:我讲你听,即讲解要领;第二步:我做你看,即示范动作第三步:你做我看;即士兵练习第四步:我给你纠正,即纠正动作第五步:我再做给你看,即再进行示范第六步:你再做给我看,即再进行操作第七步:我进行小结,即课后讲评。

二、//队列训练的基本内容//首先,请大家明确两个概念:(1)什么是队列?(2)什么是条令?队列是集合人员的队列形式、动作的总称,它包括单个军人队列动作、部队(分队)队列动作、队列指挥三项内容。

而条令是用简明条文规定,通过命令颁布的关于军队战斗、训练、生活等行动的准则。

背包九讲(DD)

背包九讲(DD)

背包问题九讲目录第一讲 01背包问题第二讲完全背包问题第三讲多重背包问题第四讲混合三种背包问题第五讲二维费用的背包问题第六讲分组的背包问题第七讲有依赖的背包问题第八讲泛化物品第九讲背包问题问法的变化附:USACO中的背包问题前言本篇文章是我(dd_engi)正在进行中的一个雄心勃勃的写作计划的一部分,这个计划的内容是写作一份较为完善的NOIP难度的动态规划总结,名为《解动态规划题的基本思考方式》。

现在你看到的是这个写作计划最先发布的一部分。

背包问题是一个经典的动态规划模型。

它既简单形象容易理解,又在某种程度上能够揭示动态规划的本质,故不少教材都把它作为动态规划部分的第一道例题,我也将它放在我的写作计划的第一部分。

读本文最重要的是思考。

因为我的语言和写作方式向来不以易于理解为长,思路也偶有跳跃的地方,后面更有需要大量思考才能理解的比较抽象的内容。

更重要的是:不大量思考,绝对不可能学好动态规划这一信息学奥赛中最精致的部分。

你现在看到的是本文的1.0正式版。

我会长期维护这份文本,把大家的意见和建议融入其中,也会不断加入我在OI学习以及将来可能的ACM-ICPC的征程中得到的新的心得。

但目前本文还没有一个固定的发布页面,想了解本文是否有更新版本发布,可以在OIBH论坛中以“背包问题九讲”为关键字搜索贴子,每次比较重大的版本更新都会在这里发贴公布。

目录第一讲 01背包问题这是最基本的背包问题,每个物品最多只能放一次。

第二讲完全背包问题第二个基本的背包问题模型,每种物品可以放无限多次。

第三讲多重背包问题每种物品有一个固定的次数上限。

第四讲混合三种背包问题将前面三种简单的问题叠加成较复杂的问题。

第五讲二维费用的背包问题一个简单的常见扩展。

第六讲分组的背包问题一种题目类型,也是一个有用的模型。

后两节的基础。

第七讲有依赖的背包问题另一种给物品的选取加上限制的方法。

第八讲泛化物品我自己关于背包问题的思考成果,有一点抽象。

背包问题----完全背包(最优方案总数分析及实现)

背包问题----完全背包(最优方案总数分析及实现)

背包问题----完全背包(最优⽅案总数分析及实现)本⼈博⽂》中已详细谈过完全背包问题,同时在博⽂》中也总结过01背包的最优⽅案总数的实现。

这⾥我们模仿01背包最优⽅案总数⽅法给出完全背包的最优⽅案求解⽅法。

重写完全背包的动态规划的状态及状态⽅程:完全背包是在N种物品中选取若⼲件(同⼀种物品可多次选取)放在空间为V的背包⾥,每种物品的体积为C1,C2,…,C n,与之相对应的价值为W1,W2,…,W n.求解怎么装物品可使背包⾥物品总价值最⼤。

设物品种类为N,背包容量为V,每种物品的体积为C[i],价值为W[i]。

⼦问题定义:F[i][j]表⽰前i种物品中选取若⼲件物品放⼊剩余空间为j的背包中所能得到的最⼤价值。

状态⽅程为:(2-2)在⽂章》中曾定义G[i][j]代表F[i][j]的⽅案总数。

这⾥我们也做相同的定义,那么最终的结果应该为G[N][V]。

由01背包转变到完全背包后G[i][j]该怎么求?对于01背包来说,G[i][j]求法如下(摘⾃:》):如果F[i][j]=F[i-1][j]且F[i][j]!=F[i-1][j-C[i]]+W[i]说明在状态[i][j]时只有前i-1件物品的放⼊才会使价值最⼤,所以第i件物品不放⼊,那么到状态[i][j]的⽅案数应该等于[i-1][j]状态的⽅案数即G[i][j]=G[i-1][j];如果F[i][j]=F[i-1][j-C[i]]+W[i] 且F[i][j]!=F[i-1][j]说明在状态[i][j]时只有第i件物品的加⼊才会使总价值最⼤,那么⽅案数应该等于[i-1][j-C[i]]的⽅案数,即G[i] [j]=G[i-1][j-C[i]];如果F[i][j]=F[i-1][j-C[i]]+W[i] 且F[i][j]=F[i-1][j]则说明即可以通过状态[i-1][j]在不加⼊第i件物品情况下到达状态[i][j],⼜可以通过状态[i-1][j-C[i]]在加⼊第i件物品的情况下到达状态[i][j],并且这两种情况都使得价值最⼤且这两种情况是互斥的,所以⽅案总数为G[i][j]=G[i-1][j-C[i]]+ G[i-1][j]。

浅谈几类背包题 25页PPT文档

浅谈几类背包题 25页PPT文档
泛化物品的并: 因为两个泛化物品之间存在交集,所以不能同
时两者都取,那么我们就需要求泛化物品的并 ,对同一体积,我们需要选取两者中价值较大 的一者,效率O(C)。
树形依赖背包(选课)
考虑对以i为根的子树的处理,假设当前需要处 理i的一个子节点s,体积v,价值w。
如果我们在当前的Fi中强制放入物品s后作为以s 为根的子树的初始状态的话,那么处理完以s为 根的子树以后,Fs就是与Fi有交集的泛化物品( 实际上是Fs包含Fi),同时,Fs必须满足放了物 品s,即Fs[j] (v>j>=0)已经无意义了,而 Fs[j](C>=j>=v)必然包含物品s。
下一步只要求Fs与Fi的并,就完成了对一个子节 点的处理。
树形依赖背包(选课)
对于当前节点i,我们找到一个子节点s。
编号 0 1 2 3 4 5 … …
F把i Fi赋a0值给a1Fs,a作2 为这a3棵子a树4 的a初5 始状……态。
编号 0 1 2 3 4 5 …

i
F递s 归a处0 理以a1s为根a2的子a3树。a4
定义:考虑这样一种物品,它并没有固定的费 用(体积)和价值,而是它的价值随着你分配 给它的费用(体积)变化而变化。
泛化物品
泛化物品可以用一个一维数组来表示体积与价 值的关系G[j]表示当体积为j的时候,相对应的 价值为G[j] (C>=j>=0)。
显然,之前的背包动规数组Fi,就是一件泛化 物品,因为Fi[j]表示的正是体积为j的时候的最 大价值。同样的,多件物品也是可以合并成一 件泛化物品。
单调队列优化
对于多次背包,用最常见的状态表示是用F[i,j] 表示前i种物品,总体积不超过j的最大价值总 和。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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)的算法这个算法使用一维数组,先看伪代码: for i=1..N for v=0..Vf[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)。

相关文档
最新文档