1.動態規划解決0-1背包問題
0-1背包問題:給定n種物品和一個背包.物品i的種類為wi,價值為vi,背包容量為C.問:應該如何選擇裝入背包的物品,使得裝入背包中物品的總價值最大?
其中每種物品只有兩種選擇,即裝入背包和不裝入背包.
##首先找到最優子結構
##然后找到遞歸關系
##算法描述在下
通過遞歸,將所有的結果值保存在一個矩陣中

/** * 動態規划0-1背包算法 * @author 鄒齡晉 * 答案:15 11001 */ public class Demo { public static void main(String[] args) { int [] w = {2,2,6,5,4};//對應重量 int [] v = {6,3,5,4,6};//對應價值 int c = 10;//總質量 int [][] m = new int[v.length][c+1];//定義m二維數組用來表示所有的價值,m[i][j]表示第i物品裝入容量為j的背包的最大值 int [] x = new int[w.length]; //解空間集 Knapsack(v,w,c,m); traceback(m,w,c,x); System.out.println("m[0][c]="+m[0][c]); for(int i=0;i<x.length;i++){ System.out.print(x[i]+" "); } System.out.println(); for(int i=0;i<v.length;i++){ for(int j=0;j<c+1;j++){ System.out.print(m[i][j]+"\t"); } System.out.println(); } } public static void traceback(int [][]m,int []w,int c,int []x){ int n = w.length-1; for(int i=0;i<n;i++) if(m[i][c]==m[i+1][c]) x[i] = 0; else{ x[i] = 1; c-=w[i]; } x[n] = (m[n][c]>0)?1:0; } public static void Knapsack(int v[],int w[],int c,int [][]m){ int n = v.length-1; int jMax = Math.min(w[n]-1, c); for(int j=0;j<=jMax;j++) m[n][j] = 0; for(int j=w[n];j<=c;j++) m[n][j] = v[n]; for(int i=n-1;i>=0;i--){ jMax = Math.min(w[i]-1, c); for(int j=0;j<=jMax;j++) m[i][j] = m[i+1][j]; for(int j=w[i];j<=c;j++) m[i][j] = Math.max(m[i+1][j],m[i+1][j-w[i]]+v[i]); } } }

m[0][c]=15 1 1 0 0 1 0 0 6 6 9 9 12 12 15 15 15 0 0 3 3 6 6 9 9 9 10 11 0 0 0 0 6 6 6 6 6 10 11 0 0 0 0 6 6 6 6 6 10 10 0 0 0 0 6 6 6 6 6 6 6
看完程序后我們看下面兩個圖幫助理解