完全背包
完全背包和01背包的區別:
完全背包:物品可以無限使用,遍歷順序沒有強制規定,可以先物品后背包,反之亦可以
01背包: 物品只能使用一次,遍歷順序為先物品后背包
go代碼實現
package main
import (
"fmt"
)
/*
wei,是重量數組
value,是價值數組
bagWei, 是背包容量
返回值:是背包可以裝的物品的最大價值
*/
//先遍歷背包,后遍歷物品
func CompletePack1(wei, value []int ,bagWei int) int {
//初始化,默認為0
dp := make([]int,bagWei+1)
for i:=0; i<len(dp); i++ {
for j := 0; j<len(wei); j++ {
if wei[j]<=i {
dp[i] = max(dp[i],dp[i-wei[j]]+value[j])
}
}
}
return dp[bagWei]
}
//先遍歷物品,再遍歷背包
func CompletePack2(wei, value []int, bagWei int) int {
dp := make([]int,bagWei+1)
for i:=0; i<len(wei); i++ {
for j:=wei[i]; j<len(dp);j++ {
dp[j]= max(dp[j],dp[j-wei[i]]+value[i])
}
}
return dp[bagWei]
}
func max(a,b int) int {
if a>b {
return a
} else {
return b
}
}
func main() {
wei := []int{1,3,4}
value := []int{15,20,30}
result := CompletePack1(wei,value,4)
fmt.Println(result)
}
零錢兌換II
問題描述
給你一個整數數組 coins 表示不同面額的硬幣,另給一個整數 amount 表示總金額。
請你計算并返回可以湊成總金額的硬幣組合數。如果任何硬幣組合都無法湊出總金額,返回 0 。
假設每一種面額的硬幣有無限個。
題目數據保證結果符合 32 位帶符號整數。
思路
這個題目可以用完全背包來解決
1 確定dp
dp[i] 指的是背包容量為i時,可以湊出的組合數
組合數不考慮順序
2 確定狀態轉換規則
dp[j] = dp [j] + dp [j- coins[i]]
什么意思呢?
dp[j] 是指當前容量j的組合數,但是現在來了一個硬幣 coins[i] ,組合數必然增加,即需要加上dp [j- coins[i]] 。
3 初始化
dp[0]=1
4 遍歷順序
先物品后背包 :得到組合數
先背包后物品: 得到排列數
5 舉例
......
go代碼實現
func change(amount int, coins []int) int {
res := make([]int, amount+1)
res[0]=1
for i := 0;i<len(coins); i++ {
for j:=coins[i]; j<amount+1; j++ {
res[j]= res[j]+res[j-coins[i]]
}
fmt.Println(res)
}
return res[amount]
}