P5662 [CSP-J2019] 纪念品,有图有注释,通俗易懂,包含完全背包的讲解

10 篇文章 1 订阅

01.题目

题目链接
在这里插入图片描述

02.解题思路

2.1完全背包介绍及状态转移方程

完全背包简介

有 N 种物品和一个容量是 V 的背包,每种物品都有无限件可用。第 i 种物品的重量是 wi价值是 vi。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。( values 是价值数组,weights 是重量数组)

基于0-1背包解完全背包

for (int i = 1; i <=values.length; i++) {//i表示前i个物品
	for (int j = capacity; j >=weights[i-1]; j--) {
	//从右到左进行覆盖,当j < weights[i-1],证明第i件物品不能选
		for (int k = 0; k <= j/weights[i]; k++) {
			dp[j]=Math.max(dp[j], dp[j-k*weights[i-1]]+k*values[i-1]);
		}
	}
}

完全背包状态转态移方程

定义状态:dp(i, j) 是最大承重为 j、有前 i 件物品可选时的最大总价值
则其状态转移方程为:dp[i][j]=Math.max( dp[i][j], dp[i][j-weights[i]]+values[i] )

状态压缩

dp(j) = max { dp(j), dp(j – weights[i – 1]) + values[i – 1] } 注意(要从小到大递推)

2.2解题思路

以数据2为例子,对数据进行处理可构造出下图数组

3 3 100
10 20 15
15 17 13
15 25 16

在这里插入图片描述
数组说明:weights数组:[10, 20, 15] 表示第1天买入3个纪念品所需要的钱(单个)
valuess数组:[5, -3, -2] 表示第2天买出3个纪念品所获得的钱(单个)

2.3具体代码

	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		//分别代表未来天数 T,纪念品数量 N,小伟现在拥有的金币数量M
		int T=in.nextInt(),N=in.nextInt(),M=in.nextInt();
		int[][] data=new int[T+1][N+1];//重量数组
		int[][] incom=new int[T+1][N+1];//价值数组
		for (int i = 1; i <= T; i++) {
			for (int j = 1; j <=N; j++) {
				data[i][j]=in.nextInt();//输入数据
				incom[i-1][j]=data[i][j]-data[i-1][j];//根据输入数据构造价值数组
			}
		}
		int[] dp=new int[10000];
		for (int t = 1; t < T; t++) {
			M+=dp[M];//修改最大本金
			dp=new int[10000];//重新初始化状态数组
			//根据状态转移方程推导
			for (int i = 1; i <= N; i++) {
				for (int j = data[t][i]; j <= M; j++) {
					dp[j]=Math.max(dp[j], dp[j-data[t][i]]+incom[t][i]);
				}
			}
		}
		System.out.println(dp[M]+M);
	}

03.更多背包学习

https://blog.csdn.net/qq_46237746/article/details/123908504

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对不起,由于我是一个文本交互的模型,我无法提供图像内容或直接链接到具体的题解或解决方案。但是,我可以帮你理解CSP-J2019公交换乘问题的基本概念和解决策略,这通常涉及到数据结构、图论以及算法设计。 CSP-J2019中的公交换乘问题可能是一个典型的旅行商问题(Traveling Salesman Problem, TSP)变种,或者是寻找最优路径的问题,其中涉及到公交网络中不同站点之间的最短路径或最少换乘次数。解决此类问题通常需要使用动态规划、贪心算法或者一些启发式搜索算法,比如A*搜索或Dijkstra算法。 如果你需要了解题目的基本思路,可能会这样操作: 1. 建立一个图,节点代表公交站点,边代表两个站点之间的路线及其长度或换乘次数。 2. 对于每个节点,计算从起点到所有其他节点的最短路径,形成一个邻接矩阵或邻接表。 3. 使用动态规划方法,例如记忆化搜索,尝试所有可能的路径,每次选择当前未访问节点中距离最近的一个,直到遍历完所有节点并回到起点,记录下总的距离或换乘次数。 4. 为了优化,可以考虑使用启发式搜索策略,如用估算的总距离作为启发信息,优先探索看起来更优的路径。 如果你对具体解法有疑问,或者想了解某个步骤的详细操作,请告诉我,我会尽力解释。至于详细的题解,建议你查阅相关的代码库、论坛帖子或在线教程,它们通常会有文字描述和步骤示例。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值