Dynamic programming - understanding the knapsack problem

Conditions for using dynamic programming:

1. Optimization principle (optimal substructure properties) The substrategy of an optimization strategy is always optimal . A problem that satisfies the optimization principle, also known as having an optimal substructure property, allows us to gradually construct the optimal solution of the whole problem from the optimal solution of the subproblem in a bottom-up manner. The optimization principle is the basis of dynamic programming. If any problem loses the support of the optimization principle, it is impossible to use the dynamic programming method to calculate

 

If routes I and J are the optimal routes from A to C, then according to the optimization principle, route J must be the optimal route from B to C. (Excerpted from the courseware of gdut Institute of Planning)

 

2. No backwardness: After the stages are arranged in a certain order, for a given stage state, the state of its previous stages cannot directly affect its future decision-making, but only through the current state. In other words, each state is a complete summary of past history. This is no retrospective, also known as no retrospective.

 

3. Overlapping of subproblems (non-essential condition) This condition is a non-essential condition, but without this condition, the dynamic programming method has no advantage compared with other methods. The sub-problems generated each time are not new sub-problems, and some sub-problems are repeatedly calculated. In solving a problem, when the same sub-problem appears repeatedly , and the number of different sub-problems is relatively small, dynamic programming is effective.

Dynamic programming is essentially a technology that exchanges space for time. In the process of implementation, it has to store various states in the production process, so its space complexity is greater than other algorithms.

 

Knapsack problem: Given n items with weights w1,....wn, values ​​of v1,...,vn and a knapsack with weight W, find the most valuable subset of these items that can hold into the backpack

 

The meaning of the array element BestSolution[i][j] is for the given first i elements, the maximum value when the knapsack capacity is j.

 

Assumptions:

There are 4 items, we can go from "Add 0th item to backpack" --> "Add 0th and 1st item to backpack" --> "Add 0th and 1st and 2nd item to backpack items" ... to add all

Big problems can be solved by small problems:

For the current i-th item, given the knapsack capacity as package:

Judge first:

能不能把这个物品加入背包,即物品是否大于背包最大容量 -------》如果物品直接大于背包最大容量,那么就不能加入背包,最大价值和没有这个物品的时候一样(BestSolution[ i ][ package ] = BestSolution[ i-1 ][ package ])

如果我能够把这个物品放入背包,那么我是放进去好呢( value[i-1] + BestSolution[ i-1 ][ Package-weight [ i-1 ] ]  ),还是不放进去( BestSolution[ i-1][ Package ] )好呢?  这里就要取两种情况的最大值.

上代码:

import java.util.Scanner;

public class Solution {
	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()) {
			int n = sc.nextInt();
			
			int value[] = new int[n];
			int weight[] = new int[n];
			
			
			for(int i=0;i<n;i++) {
				value[i] = sc.nextInt();
			}
			for(int i=0;i<n;i++) {
				weight[i] = sc.nextInt();
			}
			
			int Package = sc.nextInt();
			
			//BestSolution[i][j] 表示 从 数组前 i个物品中选择,容量为j的背包的最大价值
			//行号表示物品数量,列号表示背包容量
			int BestSolution[][] = new int[n+1][Package+1];
			
			//第一列所有元素都是0,因为背包容量为0
			for(int i=0;i<=n;i++) {
				BestSolution[i][0] = 0;
			}
			//第一行所有列都是0,因为没有物品
			for(int i=0;i<=Package;i++) {
				BestSolution[0][i] = 0;
			}
			
			for(int i=1;i<=n;i++) {
				for(int j=1;j<=Package;j++) {
					//对于当前背包容量,当前物品是否装得下
					//如果背包装得下
					if(weight[i-1]<=j) {
												             
						BestSolution[i][j] = Math.max(
								//当前物品不装进去
								BestSolution[i-1][j],
								//当前物品装进去
								value[i-1]+BestSolution[i-1][j-weight[i-1]]);;
					}else {
						//装不下就和没有的最优解一样
						BestSolution[i][j] = BestSolution[i-1][j];
					}
				}
			}
			
			System.out.println("最大价值为:"+BestSolution[n][Package]);
		}
	}
}

  !!!这里容易导致理解不清楚的是:当前物品 “装进去” 指的是 :把背包中所有东西倒出来,把当前物品装进去,然后再看看剩下的容量能够装的最大价值是多少,而“剩下的容量的最大价值”,就是之前已经解决的问题。

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325600828&siteId=291194637