首页 > 代码库 > 01背包

01背包

问题描述:

给定N中物品和一个背包。物品i的重量是Wi,其价值位Vi ,背包的容量为C。问应该如何选择装入背包的物品,使得转入背包的物品的总价值为最大??

在选择物品的时候,对每种物品i只有两种选择,即装入背包或不装入背包。不能讲物品i装入多次,也不能只装入物品的一部分。因此,该问题被称为0-1背包问题。 

 1 import java.math.BigInteger;
 2 import java.util.Arrays;
 3 import java.util.Scanner;
 4 
 5 
 6 public class Main {
 7     static int[][] b;
 8     static int[] a;
 9     static int[] a1;
10     static boolean[] flag;
11     public static void main(String[] args) {
12         Scanner input = new Scanner(System.in);
13         int n,m;
14         n = input.nextInt();//物品数量
15         m = input.nextInt();//背包大小
16         a = new int[n+1];//物品质量
17         a1 = new int[n+1];//物品价值
18         for(int i=1;i<=n;i++){
19             a[i] = input.nextInt();
20         }
21         for(int i=1;i<=n;i++){
22             a1[i] = input.nextInt();
23         }
24         b = new int[n+1][m+1];//物品数量价值表
25         flag = new boolean[n+1];//是否用过
26         for(int i=1;i<=n;i++){
27             for(int j=1;j<=m;j++){
28                 //物品质量大于背包容量
29                 if(j<a[i]){
30                     b[i][j] = b[i-1][j];
31                 //物品质量小于背包容量有两种情况
32                 //1.物品不放入背包
33                 //2.物品放入背包
34                 }else{
35                     b[i][j] = Math.max(b[i-1][j], b[i-1][j-a[i]]+a1[i]);
36                 }
37             }
38             
39         }
40         //检测使用那些物品
41         int j = m;
42         for(int i=n;i>0;i--){
43             if(b[i][j]>b[i-1][j]){
44                 flag[i] = true;
45                 j = j-a[i];
46             }
47         }
48         System.out.print("使用了:");
49         for(int i=1;i<=n;i++){
50             if(flag[i])
51                 System.out.print(i+" ");
52         }
53         System.out.println();
54         System.out.println("最大值:"+b[n][m]);
55     }
56 
57 }

 

01背包