动态规划0-1背包问题

问题描述:

给定N中物品和一个背包。物品i的重量是Wi,其价值位Vi ,背包的容量为C。问应该如何选择装入背包的物品,使得转入背包的物品的总价值为最大??

在选择物品的时候,对每种物品i只有两种选择,即装入背包或不装入背包。不能讲物品i装入多次,也不能只装入物品的一部分。因此,该问题被称为0-1背包问题。 

 

问题分析:令V(i,j)表示在前i(1<=i<=n)个物品中能够装入容量为就j(1<=j<=C)的背包中的物品的最大价值,则可以得到如下的动态规划函数:

(1)   V(i,0)=V(0,j)=0 

(2)   V(i,j)=V(i-1,j)  j<wi  

       V(i,j)=max{V(i-1,j) ,V(i-1,j-wi)+vi) } j>wi

(1)式表明:如果第i个物品的重量大于背包的容量,则装人前i个物品得到的最大价值和装入前i-1个物品得到的最大价是相同的,即物品i不能装入背包;第(2)个式子表明:如果第i个物品的重量小于背包的容量,则会有一下两种情况:(a)如果把第i个物品装入背包,则背包物品的价值等于第i-1个物品装入容量位j-wi 的背包中的价值加上第i个物品的价值vi; (b)如果第i个物品没有装入背包,则背包中物品价值就等于把前i-1个物品装入容量为j的背包中所取得的价值。显然,取二者中价值最大的作为把前i个物品装入容量为j的背包中的最优解。

 

package main

import (
	"fmt"
)

const (
	N = 4
	W = 5
)

var weight []int = []int{3, 2, 1, 2}
var val []int = []int{4, 3, 2, 2}
var dp [N + 1][W + 1]int
var record [N][W + 1]int //保存中间结果的记录

func init() {
	for i := 0; i < N; i++ {
		for j := 0; j <= W; j++ {
			record[i][j] = -1
		}
	}
}

//非递归方式 V(i,j)=max{V(i-1,j) ,V(i-1,j-wi)+vi) } j>wi
func solve2() int {
	length := len(val)
	for i := 0; i < length; i++ {
		for j := weight[i]; j <= W; j++ {
			dp[i+1][j] = max(dp[i][j], dp[i][j-weight[i]]+val[i])
		}
	}

	return dp[N][W]
}

//递归方式
func solve(i int, total int) int {
	result := 0
	if i >= N {
		return result
	}
	if -1 != record[i][total] {
		return record[i][total]
	}
	if weight[i] > total {
		record[i][total] = solve(i+1, total)
	} else {
		//递归求最大值
		result = max(solve(i+1, total), solve(i+1, total-weight[i])+val[i])
	}
	record[i][total] = result
	return record[i][total]
}

func max(a int, b int) int {
	if a > b {
		return a
	}
	return b
}

func main() {
	result := solve(0, W)
	fmt.Printf("best val:%v \n", result)

	result1 := solve2()
	fmt.Printf("best value1:%v\n", result1)

}

 

总结:递归实现动态规划求第N+1次最最优解与第N次最优解之间有关联,可以理解成裁剪过的探索与回溯算法

 

转载于:https://my.oschina.net/yang1992/blog/600461

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值