算法-动态规划0-1背包

package cn.com.suanfa;

/**
 * @ClassName: DP01
 * @Desc: 动态规划求解0-1背包问题 <br>
 *        1.动态规划的核心思想: 将大问题分解成小问题,从而一步步获取最优解的处理算法(有局部最优解退出全局最优解)<br>
 *        2.动态规划与分治的相同点: 将大问题分分解成小问题,通过解决小问题,来解决原问题 <br>
 *        3.动态规划与分治的不同: 动态规划各个小问题之间存在着联系,分治算法,咯咯咯小问题之间相互独立 <br>
 *        4.动态规划可通过填表的方式获得<br>
 * @author: lancelan
 * @date: 2022年12月2日 下午4:57:25 <br>
 * 
 */
public class DP01 {
	// 定义重量的数组
	public static int[] W = { 1, 4, 3 };
	// 定义物品的价值
	public static int[] VAL = { 1500, 3000, 2000 };
	// 定义不同重量的最大价值
	public static int N = 5;// 定义背包的容量
	
//	// 定义重量的数组
//		public static int[] W = { 1, 4, 3,5,7 };
//		// 定义物品的价值
//		public static int[] VAL = { 1500, 3000, 2000,233,987 };
//		// 定义不同重量的最大价值
//		public static int N = 10;// 定义背包的容量

	public static void main(String[] args) {
		/**
		 * 初始化。i行:物品,j列:背包容量,
		 */
		int[][] dp = new int[W.length + 1][N + 1]; // 列为背包,行为物品
		int[][] resource = new int[W.length + 1][N + 1]; // 存放物品
		String[][] goodsAndValue = new String[W.length + 1][N + 1];
		for (int i = 0; i <= N; i++) {
			goodsAndValue[0][i] = "";
		}
		for (int i = 0; i <= VAL.length; i++) {
			goodsAndValue[i][0] = "";
		}
		/**
		 * //开始求解二维数组dp
		 */
		for (int goods = 1; goods <= W.length; goods++) {
			for (int bagWeight = 1; bagWeight <= N; bagWeight++) {
				// 如果当前背包的容量小于第i个商品的重量,将上一行的值,复制到当前行
				if (bagWeight < W[goods - 1]) {
					dp[goods][bagWeight] = dp[goods - 1][bagWeight];
					goodsAndValue[goods][bagWeight] = goodsAndValue[goods - 1][bagWeight];
				} else {// 否则背包容量大于当前商品的重量
					/**
					 * 如果当前商品的价值+背包减去当前商品的重量后,剩余容量的价值 > 上一行的价值,就将上一行的价值赋给当前行
					 */
					// 当前商品价值
					int curGoodsValue = VAL[goods - 1];
					// 当前商品的重量
					int curWeight = W[goods - 1];
					// 剩余空间=当前背包容量 - 当前商品重量. 可能是0.
					int leftWeight = bagWeight - curWeight;
					// 剩余空间的最大价值。根据剩下空间去查找最大价值。
					// 就是上一行中的
					int leftValue = dp[goods - 1][leftWeight];
					// 上一行的价值
					int lastValue = dp[goods - 1][bagWeight];
					if (curGoodsValue + leftValue > lastValue) {
						dp[goods][bagWeight] = curGoodsValue + leftValue;
						resource[goods][bagWeight] = 1;
						goodsAndValue[goods][bagWeight] = "物品:" + goods + "-价值:" + curGoodsValue + "," + goodsAndValue[goods - 1][leftWeight];
					} else { // 小于上一行的价值,使用上一行替换
						dp[goods][bagWeight] = dp[goods - 1][bagWeight];
						goodsAndValue[goods][bagWeight] = goodsAndValue[goods - 1][bagWeight] + "";
					}
				}
			}
		}

		System.out.print("物品|");
		for (int i = 0; i <= N; i++) {
			System.out.print(" 容量" + (i) + "|");
		}
		System.out.println();
		for (int i = 0; i < dp.length; i++) {
			System.out.print("物品" + i + ":     ");
			for (int j = 0; j < dp[1].length; j++) {
				System.out.print(dp[i][j] + " | ");
			}
			System.out.println();
		}
		System.out.println("----------------------------------");
		for (int i = 0; i < goodsAndValue.length; i++) {
			System.out.print("物品" + i + ":     ");
			for (int j = 0; j < goodsAndValue[1].length; j++) {
				System.out.print(goodsAndValue[i][j] + " | ");
			}
			System.out.println();
		}
		System.out.println("----------------------------------");
		int i = resource.length - 1;
		int j = resource[0].length - 1;
		while (i > 0 && j > 0) {
			if (resource[i][j] == 1) {
				System.out.printf("第%s个商品放到背包中\n", i);
				j -= W[i - 1];// 减掉当前商品的重量,为剩余重量
			}
			i--;
		}

	}
}

结果:

猜你喜欢

转载自blog.csdn.net/lan861698789/article/details/128153204