算法基础-动态规划 (1) 01背包问题

2 篇文章 0 订阅
1 篇文章 0 订阅

最近闲的无聊,算法一直是弱项,正好hihocoder上面开始了每周的比赛,

这周的题目是01背包问题。正好归纳和总结一下。

所有的动态规划问题都两个特点:

1、重复子问题一个问题可以转化成几个同类型的子问题。

2、后无关性:前一个问题产生的决策和结果,对下一个问题没有影响。

说白了,就是你能吧问题写成简单的数学递归表达式:

对于01背包问题,建模很关键,

这里面有几个关键量 

物品个数N

能容纳的重量M

每个物品的价值V(i)

每个物品的重量w(i)

我们要想好这个数学表达式

对于每个物品而言,有两种状态,被选上和不被选上, 即0和1状态。而对整个背包而言  能够承受的重量就是里面物品的加和,同样价值一样也是加和。

我们希望背包尽可能装得多,而且产生的价值最大,(最重要的的是总价值最高)

所以整个表达式应该以价值作为衡量因素。

下面是表达式:



N个物品,背包有M重量空余,等于在前N-1选择最大的,一种是不选择第N-1个物品,另一种是选择第N-1个物品,并占据了背包Wn的重量,但提供了Vn的价值。


下面是三种代码形式,孰优孰劣,大家一眼就能开出来。

	public int getcurrentVlue(int i,int j){
		if(i==0){
			if(j>=0) return 0;
		}
		if(j<0) return Integer.MIN_VALUE;		
		return max (getcurrentVlue(i-1, j),getcurrentVlue(i-1, j-w[i-1])+v[i-1]);
	}


	public int getvalue(int sum,int wei){
		int[] [] value =new int [sum][wei];
		for(int i=1;i<sum;i++){
			for(int j=0;j<wei;j++){
				if(j<w[i-1]) value[i][j] = value[i-1][j];
				else{
					value[i][j] = max (value[i-1][j],value[i-1][j-w[i-1]]+v[i-1]);
				}
			}
		}
		return wei;
	}

public int getvalues(int sum, int wei) {
		int[] value = new int[wei + 1];
		for (int i = 1; i < sum + 1; i++) {
			for (int j = wei; j > w[i - 1] - 1; j--) {
				value[j] = value[j] > value[j - w[i - 1]] + v[i - 1] ? value[j]
						: value[j - w[i - 1]] + v[i - 1];
			}
		}
		return value[wei];
	}


显然第三种效果最好。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值