动态规划之0/1揹包问题(java实现)

1、开篇:

2020届小白开始准备互联网笔试了,要想拿下笔试,动态规划问题得写的特别6啊!在此总结一篇最基本的0/1揹包问题的动态规划问题,其实笔试题中很多动态规划问题都是在此基础上的改版,原理是差不多的。

 2、题目:

假设现有容量10kg的揹包,另外有3个物品,分别为a1,a2,a3。物品a1重量为3kg,价值为4;物品a2重量为4kg,价值为5;物品a3重量为5kg,价值为6。将哪些物品放入揹包可使得揹包中的总价值最大?

 3、分析:

     首先想到的,一般是穷举法,一个一个地试,对于数目小的例子适用,如果容量增大,物品增多,这种方法就无用武之地了。

     其次,可以先把价值最大的物体放入,这已经是贪婪算法的雏形了。如果不添加某些特定条件,结果未必可行。

     最后,也是最重要的,就是动态规划的思路了。先将原始问题一般化,欲求揹包能够获得的总价值,即欲求前i个物体放入容量为m(kg)揹包的最大价值arr[i][m]——使用一个数组来存储最大价值,当m取10,i取3时,即原始问题了。而前i个物体放入容量为m(kg)的揹包,又可以转化成前(i-1)个物体放入揹包的问题。下面使用数学表达式描述它们两者之间的具体关系。

  表达式中各个符号的具体含义。

  w[i] :  第i个物体的重量;

  p[i] : 第i个物体的价值;

  c[i][m] : 前i个物体放入容量为m的揹包的最大价值;

  c[i-1][m] : 前i-1个物体放入容量为m的揹包的最大价值;

  c[i-1][m-w[i]] : 前i-1个物体放入容量为m-w[i]的揹包的最大价值;

由此可得递推公式:

  c[i][m]=max{c[i-1][m-w[i]]+pi , c[i-1][m]}

4、java代码实现:

package test;

/**
 * 
 * @author FHY
 * 揹包问题动态规划实现
 *
 */
public class DynamicDemo {
	
	public static void main(String[] args) {
		int[] value = {4,5,6};
		int[] weight = {3,4,5};
		getMaxValue(10, value, weight);
		
	}
	
	public static void getMaxValue(int total, int[] value, int[] weight){
		int m = total; //揹包的最大容量
		int n = value.length; //商品个数
		
		//初始化物品价值矩阵
		int[][] arr = new int[n+1][m+1];

		for(int i = 0; i<= m; i++)
			arr[0][i] = 0;
		
		for(int j = 0; j <= n; j++)
			arr[j][0] = 0;
		
		//动态规划核心代码
		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= m; j++){				
				if(weight[i-1] <= j){
					if(arr[i-1][j] < arr[i-1][j-weight[i-1]]+value[i-1])
						arr[i][j] = arr[i-1][j-weight[i-1]]+value[i-1];
					else 
						arr[i][j] = arr[i-1][j];
				}else {
					arr[i][j] = arr[i-1][j];
				}				
			}
		}
		//输出物品价值矩阵
		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= m; j++){
				System.out.print(arr[i][j]);
			}
			System.out.println();
		}
	}

}

本文解析来自:cnblogs.com/lfeng1205/p/5981198.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章