动态规划入门-01背包问题

动态规划入门-01背包问题

问题描述

假设你有个最大载重量为 300 k g 300kg 300kg的背包,有4个物品。它们的重量分别为 123 k g , 88 k g , 93 k g , 100 k g 123kg,88kg,93kg,100kg 123kg,88kg,93kg,100kg,价值分别为$$10,$19,$8,$20$。

请问背包内最大可以放入多少价值的物品?


问题求解

这个问题被称为01背包问题,是典型的动态规划例题。

确定状态
确定选择
定义dp数组
确定边界条件
寻找状态转移
求解答案

这里的价值是我们要优化的目标值,物品数目和重量为两个状态,所以依据这两个状态可以定义二维dp数组。

对于每个物品,我们有两种选择,即放入背包或者不放入背包。

我们设数组f[n][w]代表前n个物品在w容量的背包里可以放入的最大价值。

当没有物品或者背包容量为0时,价值显然是0:
f [ 0 ] [ w ] = f [ n ] [ 0 ] = 0 f[0][w] = f[n][0] = 0 f[0][w]=f[n][0]=0
我们求解的是背包内的物品价值最大化,则状态转移为:
f [ i ] [ j ] = { f [ i − 1 ] [ j ] , w [ i ] > j m a x ( f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − w [ i ] ] + v [ i ] ) , w [ i ] ≤ j f[i][j] = \begin{cases} f[i-1][j] &, w[i]>j \\ max(f[i-1][j],f[i-1][j-w[i]] + v[i]) &, w[i] \leq j \end{cases} f[i][j]={f[i1][j]max(f[i1][j],f[i1][jw[i]]+v[i]),w[i]>j,w[i]j


代码实现

Java

public class mian {
	static int maxVal(int[] w,int[] v,int maxw) {
		int n = w.length;
		int[][] f = new int[n][maxw+1];
		for (int i = 1; i < n; i++) {
			for (int j = 1; j <= maxw; j++) {
				if (j < w[i]) {
					f[i][j] = f[i-1][j];
				} else {
					f[i][j] = Math.max(f[i-1][j-w[i]] + v[i],f[i-1][j]);
				}
			}
		}
		return f[n-1][maxw];
	}
	public static void main(String[] args) {
		int[] w = {123, 88, 93, 100};
		int[] v = {10, 19, 8, 20};
		int maxw = 300;
		System.out.println(maxVal(w,v,maxw)); // 47
	}
}

你可能感兴趣的:(数据结构与算法,算法,动态规划,java)