【动态规划】多重背包问题

这篇文章比较粗糙,因为是面向掌握了01背包问题的读者,如若没有此基础请看上期文章;对于有01背包问题基础的读者肯定一看就懂

1. 问题描述

===========================================================================

有n个物品,第i个物品的重量与价值分别为w[i]与v[i]且第i种物品最多有s[i] 件。背包容量为c,试问在每个物品不超过其上限的件数(物品必须保持完整)的情况下,如何让背包装入的物品具有更大的价值总和。

与01背包问题不同,物品的数量不再是一个,而是多个,那么物品的选择也不再是选与不选,而是选0个,选1个,选2个。。。选s[i]个;然后求出这些组合中的价值总和最大的组合的值即为解

01背包的通式:

{ ∑ i = 1 n w i x i ≤ C x i ∈ { 0 , 1 } , 1 ≤ i ≤ n \begin{cases} \sum_{i=1}^n w_ix_i \leq C\\ x_i\in\{0,1\},1\leq i\leq n \end{cases} {∑i=1n​wi​xi​≤Cxi​∈{0,1},1≤i≤n​

多重背包通式:

{ ∑ i = 1 n w i k ≤ C k ∈ { 0 , 1 , 2 , . . . , s [ i ] } , 1 ≤ i ≤ n \begin{cases} \sum_{i=1}^n w_ik \leq C\\ k\in\{0,1,2,…,s[i]\},1\leq i\leq n \end{cases} {∑i=1n​wi​k≤Ck∈{0,1,2,…,s[i]},1≤i≤n​

2. dp方程

===========================================================================

有了01背包的基础,构造多重背包的递推通式应该很简单了(自顶向下构造多重背包)

m ( i , j ) = { m a x { m ( i − 1 , j ) , m ( i − 1 , j − k ∗ w i ) + v i } , j ≥ k ∗ w i , k ∈ { 0 , 1 , 2… , s [ i ] } m ( i − 1 , j ) , 0 ≤ j < k ∗ w i m(i,j)= \begin{cases} max{\{m(i-1,j),m(i-1,j-k*w_i)+v_i\}}, j\geq k*w_i,k\in\{0,1,2…,s[i]\}\\ m(i-1,j),0\leq j < k*w_i \end{cases} m(i,j)={max{m(i−1,j),m(i−1,j−k∗wi​)+vi​},j≥k∗wi​,k∈{0,1,2…,s[i]}m(i−1,j),0≤j<k∗wi​​

我们可以对比01背包的通式(自顶向下构造01背包):

m ( i , j ) = { m a x { m ( i − 1 , j ) , m ( i − 1 , j − w i ) + v i } , j ≥ w i m ( i − 1 , j ) , 0 ≤ j < w i m(i,j)= \begin{cases} max{\{m(i-1,j),m(i-1,j-w_i)+v_i\}}, j\geq w_i\\ m(i-1,j),0\leq j < w_i \end{cases} m(i,j)={max{m(i−1,j),m(i−1,j−wi​)+vi​},j≥wi​m(i−1,j),0≤j<wi​​

3. 核心代码

===========================================================================




for(int i=1;i<=n;++i) {

	for(int j=1;j<=c;++j) {

		for(int k=0;k<=s[i]&&k*w[i]<=j;++k) {

			dp[i][j]=Math.max(dp[i][j], dp[i-1][j-k*w[i]]+k*v[i]);

		}

	}

}



4. 小试牛刀

===========================================================================

原题链接:https://acm.hnucm.edu.cn/JudgeOnline/

题目描述

在某网络游戏中提供了一个道具库,在道具库中每种道具均有若干件(数量已知),游戏玩家购买一件道具将获得一定的魅力值。

已知每种道具的价格和魅力值,请编写一个程序,在总价格不超过某个上限的情况下使得所购道具的魅力值之和达到最大。

输入

每组测试数据的输入有n+1行,n表示道具的种类。(n<=100,p<=10000)

第1行包含两个正整数,分别表示道具种类数n和总价值的上限p,两个数字之间用空格隔开。

第2行到第n+1行分别对应于第1种道具到第n种道具的信息,每1行包含三个正整数,两个数字之间用空格隔开,三个正整数分别表示某一种道具的数量、单个道具的价格和魅力值。

输出

每组测试数据的输出只有一行,即道具魅力值的最大和。

样例输入

3 10

2 2 3

1 5 10

2 4 12

样例输出

27


import java.util.Scanner;

public class Main {



	public static void main(String[] args) {

		Scanner scanner=new Scanner(System.in);

		int n,c;

		int[] s,w,v;

		int[][] dp;

		while(scanner.hasNext()) {

			n=scanner.nextInt();

			c=scanner.nextInt();

			s=new int[n+1];

			w=new int[n+1];

			v=new int[n+1];

			dp=new int[n+1][c+1];

			for(int i=1;i<=n;++i) {

				s[i]=scanner.nextInt();

				w[i]=scanner.nextInt();

				v[i]=scanner.nextInt();

			}			



### 最后

**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。

* * *

![](https://img-blog.csdnimg.cn/img_convert/db43eefad2f3d098f0dd488609660bc9.webp?x-oss-process=image/format,png)

![](https://img-blog.csdnimg.cn/img_convert/77b78cd4d21feeb27940c851684a739d.webp?x-oss-process=image/format,png)


			}			



### 最后

**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。

* * *

[外链图片转存中...(img-iUzRTxik-1720110191033)]

[外链图片转存中...(img-v07O6QTb-1720110191034)]


基础篇 1、 算法有哪些特点?它有哪些特征?它和程序的主要区别是什么? 2、 算法的时间复杂度指的是什么?如何表示? 3、 算法的空间复杂度指的是什么?如何表示? 4、 什么是最坏时间复杂性?什么是最好时间复杂性? 5、 什么是递归算法?什么是递归函数? 6、 分治法的设计思想是什么? 7、 动态规划基本步骤是什么? 8、 回溯法与分枝限界法之间的相同点是什么?不同之处在哪些方面? 9、 分枝限界法的基本思想是什么? 10、 限界函数的功能是什么? 11、 设某一函数定义如下: 编写一个递归函数计算给定x的M(x)的值。 12、 已知一个顺序表中的元素按元素值非递减有序排列,编写一个函数删除表中多余的值相同的元素。 13、 分别写出求二叉树结点总数及叶子总数的算法。 分治术 14、 有金币15枚,已知其中有一枚是假的,而且它的重量比真币轻。要求用一个天平将假的金币找出来,试设计一种算法(方案),使在最坏情况下用天平的次数最少。 15、 利用分治策略,在n个不同元素中找出第k个最小元素。 16、 设有n个运动员要进行网球循环赛。设计一个满足以下要求的比赛日程表。 (1)每个选手必须与其它n-1选手各赛一次; (2)每个选手一天只能赛一次。 17、 已知序列{503,87,512,61,908,170,897,275,652,462},写一个自底向上的归并分类算法对该序列作升序排序,写出算法中每一次归并执行的结果。 贪心法 18、 设有n个文件f1,f2,…,fn要求存放在一个磁盘上,每个文件占磁盘上1个磁道。这n个文件的检索概率分别是p1,p2,…,pn,且 =1。磁头从当前磁道移到被检索信息磁道所需的时间可用这两个磁道之间的径向距离来度量。如果文件fi存放在第i道上,1≤i≤n则检索这n个文件的期望时间是 。其中d(i,j)是第i道与第j道之间的径向距离。磁盘文件的最优存储问题要求确定这n个文件在磁盘上的存储位置,使期望检索时间达到最小。试设计一个解此问题的算法,并分析算法的正确性与计算复杂性。 19、 设有n个正整数,编写一个算法将他们连接成一排,组成一个最大的多位整数。用贪心法求解本题。 20、 键盘输入一个高精度的正整数N(此整数中没有‘0’),去掉其中任意S个数字后剩下的数字按原左右次序将组成一个新的正整数。编程对给定的N和S,寻找一种方案使得剩下的数字组成的新数最小(输出应包括所去掉的数字的位置和组成的新的正整数,N不超过240位)。 21、 对于下图给出的有向网,写出用Dijkstra方法求从顶点A到图中其它顶点的最短路径的算法,并写出执行算法过程中顶点的求解次序及从顶点A到各顶点路径的长度。 22、 对于上图给出的有向图,写出最小成本生成树,给出求解算法动态规划 23、 求出上图中每对结点间的最短距离的算法,并给出计算结果。 24、 下图中给出了一个地图,地图中每个顶点代表一个城市,两个城市间的连线代表道路,连线上的数值代表道路的长度。现在,想从城市A到达城市E,怎样走路程最短,最短路程的长度是多少? 25、 已知序列a1,a2,…,an,试设计一算法,从中找出一子序列 ai1 < ai2 < … E。试用动态规划的最优化原理求出A->E的最省费用。 29、 已知如下图,写出用动态规划求最短路径的递推关系式,并写出求从源点A0到终点A3 的最短路径过程。给出求解算法。 6 A1 A2 5 5 2 A0 A3 3 4 4 B1 B2 5 搜索与遍历问题 30、 已知有向图G=,试设计一算法以判断对于任意两点u和v,是否存在一条从u到v的路径,并分析其复杂度。 31、 对于给定的一个二叉树T(如下图) a) 设计一个算法,统计二叉树中结点总数; b) 设计一个算法,求二叉树最大宽度及最大宽度所在深度。 32、 判近亲问题。给定一个家族族谱,为简化问题起见,假设家族中的夫妻关系只表示男性成员。设用线性表存储家族成员,用成员的父指针指向其生父。编写一个在此种族谱表示方式下的算法,判断给定的二个家族成员是否是五代内的近亲。(提示:家族成员的表示方式应与搜索方式相适应。) 33、 完全二叉树定义为:深度为K,具有N个结点的二叉树的每个结点都与深度为K的满二叉树中编号从1至N的结点一一对应。(1)写一个建立二叉树的算法。(2)写一个判别给定的二叉树是否是完全二叉树的算法。 34、 编写计算整个二叉树高度的算法(二叉树的高度也叫二叉树的深度)。 35、 编写计算二叉树最大宽度的算法(二叉树的最大宽度是指二叉树所有层中结点个数的最大值)。 回溯法 36、 (组合问题)求出从自然数1,2,…,n中任取r个数的所有组合。 37、 传教士与野人渡河问题。有M个传教士和M个野人准备渡河,船一次最多载2人,任何时刻野人数不能多于传教士数,但允许全部为野人。编写算法给出合理的渡河计划。 38、 某乡有n个村庄,有一个售货员,他要到各个村庄去售货,各村庄之间的路程s是已知的,且A村到B村与B村到A村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为1。试设计一个算法,帮他选择一条最短的路。 39、 设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设wi,j是从供应商j处购得的部件i的重量,ci,j是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计。 40、 设有n件工作分配给n个人。为第i个人分配工作j所需的费用为ci,j 。试设计一个算法,计算最佳工作分配方案,为每一个人都分配1 件不同的工作,并使总费用达到最小。 41、 编写程序求解骑士巡游问题:在n行n列的棋盘上(如n=8),假设一位骑士(按象棋中“马走日”的行走法)从初始坐标位置(x1,y1)出发,要遍访(巡游)棋盘中的每一个位置一次。请编一个程序,为骑士求解巡游“路线图”(或告诉骑士,从某位置出发时,无法遍访整个棋盘 — 问题无解骑士巡游)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值