1. 程式人生 > >一道美團面試題(揹包問題)的兩種思路

一道美團面試題(揹包問題)的兩種思路

大家好,用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
}

謝謝閱讀

































上天啊,賜我一個女朋友吧