一道美团面试题(背包问题)的两种思路

大家好,用CSDN很多年了,一直在吸取养分,很感激.今天心血来潮,咱也贡献一个.
01 一道面试题
从n个商品中,选择一些物品使其在不大于背包容量时价值最大.
001 动态规划法
下面是代码
总体上来讲,动态规划就是找最优子结构,
假设已经找到了选出物品的最佳组合,那么被选中的商品中去掉一个,这一个被去掉的商品
同样的在可选择商品中也去掉,那么只要现在去掉之后的商品组合任然满足在可选商品中
是价值最大的,那么就是找到了最优子结构

package main

import (
	"fmt"
)

// w 重量数组
var w  = []int{0,5,2,4,2,3}
// 价值数组
var v  = []int{0,3,8,5,4,6}
// 背包最大可承受重量
var  maxBearWeight = 10
func main(){
	wl:=len(w)
	c:=[7][12]int{}
	for i:=1;i<wl;i++{
		for j:=1;j<=maxBearWeight;j++{
			if w[i]>j{
				// 如果该物品的重量大于maxW,就不放入
				c[i][j]=c[i-1][j]
			}else{
				// 比较此物品放和不放是否能使得购物车价值最大
				c[i][j]=max(c[i-1][j],c[i-1][j-w[i]]+v[i])
			}
		}
	}
	fmt.Println(c)
}
//找出最大值
func max( a,b int) int{
    if a>b {
		return a
	}
		return b	
}
```002 回溯法(深度搜索)
假设有{x1,x2,x3,x4,x5.............xn}中商品,那么其实可以有{y1,y2,y3.........yn}中取法,其中yn的取值为{0,1},
0表示不拿,1表示拿 
回溯需要用到树结构
![在这里插入图片描述](https://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Treedatastructure.png/450px-Treedatastructure.png)
每一种商品都有两个状态,0 1;
那么,用一个零点为树根,左孩子为有该商品,右孩子为没有该商品,所以有2的n次方情况
但是,如果搜索2n次方,不就和暴力没什么区别吗?
所以,加入一件商品要判断两种
第一 该商品与当前重量之和不能大于限制条件
第二 该商品加上以后要添加进来的商品的不能大于已经发现的最大值
if currentValue+getRemainValue(l+1) > maxValue	{
		Backtrack(l+1)
	}
	

// 回溯算法
package main

import (
“fmt”
)

var Weight=[]int{0,2,5,4,2}
var Value=[]int{0,6,3,5,4}

var maxValue int
var maxBearWeight =10

var currentValue int
var currentWeight int

func main(){
Backtrack(0)
fmt.Println(maxValue)
}
func Backtrack(l int){
if l >= len(Weight){
// fmt.Println(maxValue)
return
}
// 当前的重量加起来大于背包承受的重量
if currentWeight+Weight[l] < maxBearWeight{
currentWeight+=Weight[l]
currentValue+=Value[l]
maxValue=currentValue
Backtrack(l+1)
currentValue-=Value[l]
currentWeight-=Weight[l]
}
// 如果不加该物品的情况下,判断是否值得深度搜索下去
if currentValue+getRemainValue(l+1) > maxValue {
Backtrack(l+1)
}
}
func getRemainValue(L int) int{
val:=0
for i:=L;i<len(Weight);i++{
val+=Value[i]
}
return val
}

谢谢阅读

































上天啊,赐我一个女朋友吧

















猜你喜欢

转载自blog.csdn.net/qq_40592484/article/details/83544169