动态规划算法

动态规划算法——解决0-1背包问题【完全背包也可以转化为0-1背包问题解决】

import java.util.Arrays;

/**
 * 动态规划算法 —— 解决0-1背包问题
 * 
 * @author lenovo
 *
 */
public class DynamicProgram {

	public static void main(String[] args) {
		int[] weight = { 1, 4, 3 };
		int[] value = { 1500, 3000, 2000 };
		int c = 4;
		int maxValue = packageProgram(weight, value, c);
		System.out.println(maxValue);

	}

	public static int packageProgram(int[] weight, int[] value, int c) {
		// 创建一个二维数组【含义:表示放入背包中的前i个物品(包括第i个)的最大价值】
		// 长度加1是为了与第几个商品对应
		int[][] v = new int[weight.length + 1][c + 1];
		int[][] path = new int[weight.length + 1][c + 1];// 记录商品放入背包的方式,1表示有商品放入背包
		for (int i = 1; i < v.length; i++) {// 第一行不做处理
			for (int j = 1; j < v[0].length; j++) {// 第一列不做处理
				// 当前待放入背包的商品的重量大于当前背包的容量,则商品就不能放入到背包,
				// 即是当前背包的最大价值就是之前原先放入策略的价值【上一个状态的价值】
				if (weight[i - 1] > j) {
					v[i][j] = v[i - 1][j];
				} else {
					// 当前待放入背包的商品的重量小于等于当前背包的容量,则商品可以放入背包,
					// 即当前背包容量的最大价值为未放入商品前的价值与放入商品后的商品的价值加上剩余背包容量可容纳商品的最大价值
					// v[i][j] = Math.max(v[i-1][j],
					// value[i-1]+v[i-1][j-weight[i-1]]);【若想知道都有哪些商品放入到背包,需要调整,如下】
					if (v[i - 1][j] < value[i - 1] + v[i - 1][j - weight[i - 1]]) {
						v[i][j] = value[i - 1] + v[i - 1][j - weight[i - 1]];
						path[i][j] = 1;// 记录放的商品
					} else {
						//
						v[i][j] = v[i - 1][j];
					}
				}
			}
		}
		/*
		 * 遍历打印二维数组v可知当前的背包容量不同值的时候的所有价值情况
		 */
		for (int[] item : v) {
			System.out.println(Arrays.toString(item));
		}
		/*
		 * 以下方法作为扩展:知道都有哪些商品放入到背包
		 */
		int i = v.length - 1;// 二维数组的最大行下标
		int j = v[0].length - 1;// 二维数组的最大列下标
		while (i >= 0 && j >= 0) {
			if (path[i][j] == 1) {
				System.out.println(i + "号商品放入了背包");
				j -= weight[i - 1];// 当知道有这号商品放入到背包了,需要除去已放入背包的商品的重量继续找下一个
			}
			i--;
		}
		/**
		 * 返回二维数组的最后一个元素即可 动态规划思想也是采用分治法的思想:
		 * 即是打一个大问题分解成一系列小问题,求出小问题的最优解,以得到的小问题的最优解得到大问题的最优解;
		 * 但是他与分治法的不同是,他的下一个问题的解依赖于上一个问题的解
		 */
		return v[weight.length][c];
	}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值