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

10 篇文章 1 订阅
本文解析了完全背包问题的解题思路,通过实例讲解了如何使用0-1背包的方法求解,包括状态转移方程的推导,状态压缩技巧,并提供了一段Java代码实现。重点介绍了如何根据数据变化动态调整状态数组以求得最大总价值。
摘要由CSDN通过智能技术生成

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值