1. 0-1背包理论基础(一)
题目网址:https://kamacoder.com/problempage.php?pid=1046
package main
import "fmt"
func main() {
var n, bagSize int
fmt.Scanln(&n, &bagSize)
weights := make([]int, n)
values := make([]int, n)
for i := 0; i < n; i++ {
fmt.Scan(&weights[i])
}
for i := 0; i < n; i++ {
fmt.Scan(&values[i])
}
fmt.Println(solveSolution(n, bagSize, weights, values))
}
func solveSolution(n, bagSize int, weight, value []int) int {
dp := make([][]int, n)
for i := 0; i < n; i++ {
dp[i] = make([]int, bagSize+1)
}
//初始化第一排
// 初始化
for j := bagSize; j >= weight[0]; j-- {
dp[0][j] = dp[0][j-weight[0]] + value[0]
}
// 递推公式
for i := 1; i < n; i++ {
//正序,也可以倒序
for j := 0; j <= bagSize; j++ {
if j < weight[i] {
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[n-1][bagSize]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
2. 0-1背包理论基础(滚动数组)
使用滚动数组时我们要注意第二层的循环往往是倒序的。
func solveSolution2(n, bagSize int, weight, value []int) int {
// 定义 and 初始化
dp := make([]int, bagSize+1)
// 递推顺序
for i := 0; i < len(weight); i++ {
// 这里必须倒序(因为我们要用到只之前的信息,所以不能先覆盖掉,所以我们先更新后面的),区别二维,因为二维dp保存了i的状态
for j := bagSize; j >= weight[i]; j-- {
// 递推公式
dp[j] = max(dp[j], dp[j-weight[i]]+value[i])
}
}
return dp[bagSize]
}
3. 0-1分割等和子集
func canPartition(nums []int) bool {
n := len(nums)
sum := 0
for i := 0; i < len(nums); i++ {
sum += nums[i]
}
if sum%2 == 1 {
return false
}
bagSize := sum / 2
dp := make([]int, bagSize+1)
//初始化dp数组
for j := bagSize; j >= nums[0]; j-- {
dp[j] = nums[0]
}
//迭代
for i := 1; i < n; i++ {
for j := bagSize; j >= nums[i]; j-- {
//当前背包还能够装下这个物品
dp[j] = max(dp[j], dp[j-nums[i]]+nums[i])
}
}
if dp[bagSize] == bagSize {
return true
}
return false
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
4. 0-1最后一块石头的重量2
func lastStoneWeightII(stones []int) int {
sumWeight := 0
n := len(stones)
for i := 0; i < n; i++ {
sumWeight += stones[i]
}
bagSize := sumWeight / 2
dp := make([]int, bagSize+1)
//dp数组初始化
for j := bagSize; j >= stones[0]; j-- {
dp[j] = stones[0]
}
for i := 1; i < n; i++ {
for j := bagSize; j >= stones[i]; j-- {
dp[j] = max(dp[j], dp[j-stones[i]]+stones[i])
}
}
return sumWeight - 2*dp[bagSize]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}