package bagProblem
import "fmt"
func BagProblem1(weight, value []int, bagweight int) int {
// 定义一个dp[i][j],表示将任意0-i物品放入包后,在包j重量时,包中的价值最大
// 初始化dp都为0
dp := make([][]int, len(weight))
for i := 0; i < len(weight); i++ {
// 这里为bagweight+1,表示重量从0开始到bagweight
dp[i] = make([]int, bagweight+1)
}
// 初始化0号物品
for j := 0; j <= bagweight; j++ {
// 表示包能放下0号商品
if weight[0] <= j {
dp[0][j] = value[0]
}
}
// 第i个商品放入j重量的包时,会有两种情况
// 放入i的商品后,总重量超过了j,则此时包中的价值和放入i前相同 即 dp[i-1][j]
// 放入i的商品后,总重量没超过j,此时包中的价值为 dp[i-1][j-weight[i]]+value[i]
// 其中dp[i-1][j-weight[i]]代表没放入i时的最大价值
// 状态转移方程为
// dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i])
for i := 1; i < len(weight); i++ {
for j := 1; j <= bagweight; j++ {
if weight[i] > j {
dp[i][j] = dp[i-1][j]
} else {
dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i])
}
}
}
return dp[len(weight)-1][bagweight]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
// 压缩成一维数组
func BagProblem2(weight, value []int, bagweight int) int {
// 定义一个dp[j],在包j重量时,包中的最大价值
// 初始化dp都为0
dp := make([]int, bagweight+1)
// 第i个商品放入j重量的包时,会有两种情况
// 不放物品i,则此时包中的价值和放入i前相同 即 dp[j]
// 放入物品i,此时包中的价值为 dp[j-weight[i]]+value[i]、
// 状态转移方程为
// dp[j] = max(dp[j], dp[j-weight[i]]+value[i])
// 不能先遍历重量,再遍历商品
// 商品0的重量为1
// 例如求dp[4]时,j=4,i=0,需要由max(dp[4], dp[4 - weight[0]] + value[0]),即max(dp[4],dp[3] +value[0])
// 如果先遍历重量后遍历商品时会发现,dp[3]永远为0,说明每次都只取一个商品(因为dp[3]为初始化值,表示没有取过商品,进而表示每次只取一个商品)
for i := 0; i < len(weight); i++ {
for j := bagweight; j >= 0; j-- {
fmt.Println(i)
if j < weight[i] {
dp[j] = dp[j]
} else {
dp[j] = max(dp[j], dp[j-weight[i]]+value[i])
}
fmt.Println(dp)
}
}
return dp[bagweight]
}
算法 01背包问题
最新推荐文章于 2023-03-26 21:26:10 发布