0/1背包问题

0/1背包问题属于比较典型的算法了,它的关键点在于“拿不拿”。

现在我们有一个容量为M公斤的背包,n件物品,她们的重量分别是W1、W2.......Wn,他们的价值分别为C1、C2.......Cn,求能获得的最大价值。

输入:

第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30);

第2...N+1行:每行输入两个整数Wi,Ci,表示每个物品的重量和价值。

输出:

一个数,表示最大价值。

输入案例:

背包容量和物品个数:10 4

物品质量和价值:

2 1

3 3

4 5

7 9

画表格分析:

关于“拿”还是“不拿”,关键在于背包容量是否允许“拿”,拿了之后的价值是否大于不拿的价值。

DP

w[i]

v[i]

0

1

2

3

4

5

6

7

8

9

10

0

0

0

0

0

0

0

0

0

0

0

0

0

2

1

0

0

1

1

1

1

1

1

1

1

1

3

3

0

0

1

3

3

4

4

4

4

4

4

4

5

0

0

1

3

5

5

6

8

8

9

9

7

9

0

0

1

3

5

5

6

9

9

10

12

注:其中w[]代表物品的重量,v[]代表物品的价值,第一行的0-10代表背包的容量。

如果背包的容量小于该物品重量,那么只能选择“不拿”,那么

dp[i][j]=dp[i-1][j];

如果背包容量不小于物品质量,那么就需要比较“拿”的价值最大,还是不拿的价值最大。(也许减去w[i]你会有疑问,在下面总代码中会进行解释)

dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);

输出dp数组(也就是上面表格的右部):

0/1背包问题_第1张图片

最后一个元素12就是最大价值。

总代码:

public class beibao01 {
    public static void main(String[] args) {
         Scanner sc=new Scanner(System.in);
         System.out.println("请分别输入背包的容量和物品的个数:");
         int cont=sc.nextInt();
         int num=sc.nextInt();
         System.out.println("请分别输入背包的物品重量和价值:");
         int []w=new int[num+1];
         int []v=new int[num+1];
         int [][]dp=new int[num+1][cont+1];
         for(int i=1;i<=num;i++) {
             w[i]=sc.nextInt();//物品重量
             v[i]=sc.nextInt();//物品价值
         }
         
         for(int i=1;i<=num;i++) {
             for(int j=1;j<=cont;j++) {
                 if(j

你可能感兴趣的:(算法,java)