背包九讲-Go详解

本文详细介绍了背包问题,包括01背包、完全背包、多重背包、混合背包、二维背包和分组背包等类型。重点讨论了状态转移方程式和体积遍历策略,并通过实例解析了各种背包问题的解决方法。动态规划是解决背包问题的核心,理解其基本思想和应用是解题的关键。
摘要由CSDN通过智能技术生成

背包问题本质上是动态规划的一种,一般也是通过状态转移方程式来解决问题,问题一般是以一个有固定容量或者承重的背包和一些固定体积,重量和价值的物品,填充背包从而使背包中物品的价值最大化

01背包

01背包中每个物品只有选或不选两种状态

主要关键点:01背包的主要难点就是在于状态转移方程式的确定,这一点其实也是所有动态规划的难点所在,另一个就是为何物体的体积是逆序遍历的?

在这里插入图片描述
代码如下:

func main() {
   
	//背包容积
	var v int
	//物体数量
	var n int
	fmt.Scanf("%d", &n)
	fmt.Scanf("%d", &v)

	//物体体积
	vslice := make([]int, n,n)
	//物体价值
	wslice := make([]int, n,n)
	for i := 0; i < n; i++ {
   
		fmt.Scan(&vslice[i], &wslice[i])
	}
	//记录当前体积能装入的最大价值
	dp := make([]int, v+1, v+1)
	for i := 0; i < n; i++ {
   
		//体积从大到小开始遍历
		for j := v; j >=vslice[i]; j-- {
   
				//选择是否装入物品时的最大值进行更新
				dp[j] = int(math.Max(float64(dp[j]), float64(dp[j-vslice[i]]+wslice[i])))
		}
	}
	fmt.Println(dp[v])
}

完全背包

基本条件跟01背包类似,唯一不同的是每个物品可以无限次选择
代码如下:

主要的区别在于体积遍历时是从当前物品的体积开始遍历,与01背包相反
func main() {
   
	//背包容积
	var v int
	//物体数量
	var n int
	fmt.Scanf("%d", &n)
	fmt.Scanf("%d", &v)

	//物体体积
	vslice := make([]int, n,n)
	//物体价值
	wslice := make([]int, n,n)
	for i := 0; i < n; i++ {
   
		fmt.Scan(&vslice[i], &wslice[i])
	}
	dp := make([]int, v+1, v+1)
	for i := 0; i < n; i++ {
   
		//从小到大开始遍历
		for j := vslice[i]; j <= v; j++ {
   
			dp[j] = int(math.Max(float64(dp[j]), float64(dp[j-vslice[i]]+wslice[i])))
		}
	}
	fmt.Println(dp[v])
}
关于01背包和完全背包的具体讲解
1 状态转移方程式

dp是记录当前体积能装入物品的最大价值,下面这个状态转移方程式的主要含义是通过对比物品装入背包和不装入背包的最大价值

dp[j] = int(math.Max(float64(dp[j]), float64(dp[j-vslice[i]]+wslice[i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值