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