動態規劃之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

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