筆者參加美團在線筆試的時候,遇到了一道動態規劃的相關題目,很遺憾當時的筆者很是稚嫩,對算法簡直一竅不通,因而抱着求學的態度,打算入門動態規劃的時候,發現了這個經典的動態規劃(Dynamic Programming,DP)入門題--0/1揹包問題,看完大神們的解答思路,簡直頂禮膜拜,因而打算本身手動實現下,致敬大佬們。特此,摘記。算法
所謂的0/1表示的就是裝入揹包的物品只有兩種狀態(裝入與不裝入)。 OK,廢話很少說,上題:數組
條件: * 一個揹包,最大容量12Kg * 5個物品,分別的重量爲1 , 3 , 2 , 6 , 2(單位都是Kg),分別的價值爲2 , 5 , 3 , 10 , 4(這個單位任意) 問題: * 求揹包最多能裝下多少價值的物品?
OK,談下解題思路:函數
if (揹包體積j小於物品i的體積) f[i][j] = f[i-1][j] //揹包裝不下第i個物體,目前只能靠前i-1個物體裝包 else f[i][j] = max(f[i-1][j], f[i-1][j-Vi] + Wi)
最後一句的意思就是根據「爲了體積V的揹包中物體總價值最大化,N件物品中第i件應該放入揹包中嗎?」轉化而來的。Vi表示第i件物體的體積,Wi表示第i件物品的價值。這樣f[i-1][j]表明的就是不將這件物品放入揹包,而f[i-1][j-Vi] + Wi則是表明將第i件放入揹包以後的總價值,比較二者的價值,得出最大的價值存入如今的揹包之中。code
OK,上筆者本身擼的代碼:orm
package package_0_1; /** * 0/1 揹包問題 * @author xiao * */ public class Package01 { // 揹包的最大重量 public static int package_weight_max = 12; // 一共有幾種物品 public static int Total_Item = 5; // 每種物品的價值 public static int[] values= {0 , 2 , 5 , 3 , 10 , 4}; // 每種物品的重量 public static int[] Items_Weight = {0 , 1 , 3 , 2 , 6 , 2}; /* 一個二維數組,用來表示從前i個物品裏 * 選出最合適的裝進載重量爲j揹包中,使 * 得揹包裏的價值最大。i∈Items j∈{0-package_weight_max} * dp[i][j] 單位是 (價值) */ public static int dp[][] = new int[Total_Item+1][package_weight_max+1]; /** * 初始化dp二維數組 */ public static void initialize_dp() { for(int[] i : dp) { for(int j :i) { j=0; } } } /** * DP 計算遞推矩陣(求出每一個局部最優解,將其保存進二維數組,方便遞推) */ public static int DPMethod() { initialize_dp(); // 構造二維數組 for(int i = 1;i<=Total_Item;i++) { for(int j = 1;j<=package_weight_max;j++) { /* 若是揹包容量小於物品的重量,則不放入此物品, * 將放入上一物品的最大價值做爲此次的最大價值 */ if(j<Items_Weight[i]) { dp[i][j] = dp[i-1][j]; } /* 若是揹包容量足夠放下這件物品,那麼就 * 比較不放入物品時的最大價值與放入此物 * 品時的最大價值誰大,將大的做爲此次的最大價值 */ else { // GetMax(不放入物品的價值,此物品的價值+剩餘空間的最大價值) dp[i][j] = GetMax(dp[i-1][j],(dp[i-1][j-Items_Weight[i]]+values[i])); } System.out.print(dp[i][j]+" "); } System.out.println(""); } // 至此求得解 return dp[Total_Item][package_weight_max]; } /** * 求最大值 * @param i * @param j * @return */ private static int GetMax(int i, int j) { // TODO Auto-generated method stub if(i>j) { return i; }else { return j; } } public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("計算矩陣以下: "); int result = DPMethod(); System.out.println(String.format("12kg揹包最多能裝進價值爲 %d 的物品", result)); } }
OK,先記錄到這!it