Dynamic Programming
0-1背包问题
有N件物品和一个容量为V的背包。第i件物品的价格(即体积,下同)是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
这是最基础的背包问题.
相当于用f[i][j]表示前i个背包装入容量为v的背包中所可以获得的最大价值。
对于一个物品,只有两种情况
情况一: 第i件不放进去,这时所得价值为:f[i-1][j]
情况二: 第i件放进去,这时所得价值为:f[i-1][j-w[i]]+c[i]
状态转移方程为:f[i][j] = max(f[i-1][j], f[i-1][j-w[i]]+v[i])
代码:
1 import java.util.Scanner; 2 3 4 public class DynamicProgramming01 { 5 6 public static void main(String[] args) { 7 // TODO Auto-generated method stub 8 Scanner sc = new Scanner(System.in); 9 String line0 = sc.nextLine(); 10 String[] sline = line0.split(" "); 11 // for(String k:sline) 12 int v = Integer.parseInt(sline[0]); 13 int n = Integer.parseInt(sline[1]); 14 int[] w = new int[n+1]; 15 int[] c = new int[n+1]; 16 for (int i = 0; i < n; i++) { 17 String line1 = sc.nextLine(); 18 String[] sl = line1.split(" "); 19 w[i] = Integer.parseInt(sl[0]); 20 c[i] = Integer.parseInt(sl[1]); 21 } 22 System.out.println(dynamicProgramming01(w,c,v,n)); 23 sc.close(); 24 } 25 public static int dynamicProgramming01(int[] w,int[] c,int v,int n) { 26 int[][] f=new int[1001][1001]; 27 for (int i = 0; i < n + 1; i++) 28 f[i][0] = 0; 29 for (int j = 0; j < v + 1; j++) 30 f[0][j] = 0; 31 32 33 for(int i=1;i<=n;i++) { 34 35 for(int j=1;j<=v;j++) { 36 f[i][j]=f[i-1][j]; 37 } 38 // for(int j=0;j+w[i]<=v;j++) { 39 //// f[i][j]=Math.max(f[i-1][j], f[i-1][j-w[i]]+c[i]); 40 // f[i][j]=Math.max(f[i][j]+c[i], f[i-1][j+w[i]]); 41 // } 42 43 for(int j=v;j-w[i-1]>=0;j--) { 44 f[i][j]=Math.max(f[i-1][j], f[i-1][j-w[i-1]]+c[i-1]); 45 } 46 } 47 // int ans=0; 48 // for(int i=0;i<=n;i++) { 49 // for(int j=0;j<=v;j++) { 50 // ans=Math.max(ans,f[i][j]); 51 // } 52 // } 53 // return ans; 54 return f[n][v]; 55 56 } 57 public static int dynamicProgramming02(int[] w,int[] c,int v,int n) { 58 int[] f=new int[1001]; 59 for(int i=0;i<n;i++) { 60 for(int j=v;j>=w[i];j--) { 61 f[j]=Math.max(f[j-w[i]]+c[i], f[j]); 62 } 63 } 64 return f[v]; 65 } 66 67 }