一道美團面試題(揹包問題)的兩種思路
大家好,用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
}
謝謝閱讀
上天啊,賜我一個女朋友吧