0/1背包问题----动态规划实现

0/1背包问题:

由于前段时间研究了动态规划,今天就利用动态规划来分析及解决0/1背包问题!

问题描述:一个旅行者有一个最多能用M公斤的背包,现在有N件物品,
它们的重量分别是W1W2...,Wn,
它们的价值分别为v1,v2,...,vn.
若每种物品只有一件求旅行者能获得最大总价值?

问题分析:问题求的是最大的价值,我们定义f[i,j]表示前i种物体放进容量为j的背包里面获取到最大的价值,定义f[I,j]是子问题,显然,子问题具有重叠性,具有最优解性质,所以,此问题可以利用动态规划来解决,分析得到子问题最优解f[I,j]具有以下性质:

 

f[i,j]= 0{i=0 OR j=0}-----------------------------临界值

f[i,j]= f[i-1,j]{j<wi}----------------------------递归公式1

f[i,j]= maxf[i-1,j],f[i,j-wi]+vi),{j>wi}----------递归公式2

则n*m的f表格来记录各个过程的值(利用空间来换取时间)

下面我举例来说明,如果w={3,6,5}  v={4,3,6}  n=3,m=15

表格如图所示:

F[i][j]

J=0

J=1

J=2

J=3

J=4

J=5

J=6

V7

V8

J=9

I=0

0

0

0

0

0

0

0

0

0

0

I=1

0

0

0

4

4

4

4

4

4

4

I=2

0

0

0

4

4

4

4

4

4

7

I=3

0

0

0

4

4

6

6

6

10

10

 

如是我们利用java语言来描述o-1背包问题

public class BeiBao {
	public int beiBaoFun(int n, int m, int[] w, int[] v) {//n个物体,容量为m的背包,wi表示第i个的重量,v表示第i个中价值。
		/* f[i,j]表示取i件商品填充一个容积为j的背包的最大价值,显然问题的解就是f[n,m]*//*
		 * 显然:f[i,j]=f[i-1,j] {j<Vi} 或者 max{f[i-1,j],f[i,j-Vi]+Pi} {j>=Wi} 或者 0 {i=0 OR j=0}
		 */
		int[][] f = new int[n + 1][m + 1];
		for (int j = 0; j <= m; j++) {
			f[0][j] = 0;/* 初始化:当i=0时,f[0][j]=0 */
		}
		for (int i = 0; i <= n; i++) {
			f[i][0] = 0;/* 初始化:当j=0时,f[i][0]=0 */
		}
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				if (w[i] <= j) { /* 如果当前物品的容量小于背包容量 */
					f[i][j] = max(v[i] + f[i - 1][j - w[i]], f[i - 1][j]);
				} else {
					f[i][j] = f[i - 1][j];
				}
			}
		}
		return f[n][m];
	}
	
	private int max(int i, int j) {
		return i > j ? i : j;
	}
	
	public static void main(String[] args) {
		BeiBao bb = new BeiBao();
		int[] w = { 0, 3, 6, 5 };/* 注意:由于算法的设计问题,把第0项也要设计上去但是我在计算时候只不把他考虑进去 */
		int[] v = { 0, 4, 3, 6 };
		int res = bb.beiBaoFun(w.length - 1, 15, w, v);
		System.out.println(res);
	}
}
过程分析:
0  0  4  4  4  4  4  4   4   4   4   4   4   4   4  
0  0  4  4  4  4  4  4   7   7   7   7   7   7   7  
0  0  4  4  6  6  6  10 10  10  10  10  10  13 13

欢迎大家交流~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值