蓝桥杯经典算法题java----01背包问题

题目描述

实现一个算法求解 01 背包问题。背包问题的介绍如下:

  • 已知一个容量为 totalw​eight 的背包,有不同重量不同价值的物品,问怎样在背包容量限制下达到利益最大化。
  • 01 背包问题要求每个物品只有一个,可以选择放入或者不放入背包。

背包问题求解方法的介绍如下:

  • 用符号 Vi​ 表示第 i 个物品的价值,Wi​ 表示第 i 个物品的体积,Vi,j​ 表示当前背包容量为 j 时,前 i 个物品最佳组合对应的价值。
  • 对于当前第 i 个商品,如果包的容量比该物品体积小,即 j<Wi​。那么此时的价值与前 i−1 个的价值是一样的,即 Vi,j​=Vi−1,j​。
  • 对于当前第 i 个商品,如果包的容量能够装下该物品,即 Wi​≤j。此时需要判断装或者不装这个物品的价值对比,选择使价值更大的情况,即 Vi,j​=max(Vi​+Vi−1,j−Wi​​,Vi−1,j​)。

通过最优解回溯法找到解的组成:

  • 当 Vi,j​=Vi−1,j​时,说明没有选择第 i 个物品。
  • 当 Vi,j​=Vi−1,j−Wi​​ 时,说明装了第 i 个商品。
  • 从 i,j 的最大值一直遍历到 i=0 ,则找到了所有解。

输入描述

第一行为两个数字 totalw​eight、N,均不超过 1000。totalw​eight 含义见题干,N 为物品数量。

接下来 N 行,每行两个数字Wi​、Vi​,均不超过 1000。含义见题干。

输出描述

输出一行,为在背包容量限制下的最大化利益。

输入输出样例

示例

输入

8 5
3 4
5 5
1 2
2 1
2 3

输出

10

 

import java.util.Scanner;

// 1:无需package

// 2: 类名必须Main, 不可修改

public class Main {

     public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);

        int bagweigth = scan.nextInt();

        int num = scan.nextInt();

        int[][] sum = new int[num][bagweigth+1];

        int[] weigth = new int[num];

        int[] value = new int[num];

        for(int i = 0; i < num; i++){

            weigth[i] = scan.nextInt();

            value[i] = scan.nextInt();

        }

        sun(sum,weigth,value,bagweigth,num);

        System.out.println(sum[num - 1][bagweigth]);

        scan.close();

    }

    public static void sun(int[][] sum, int[] weigth, int[] value, int bagweigth, int num){

        for(int i = 0; i < bagweigth + 1; i++){

            if(i < weigth[0]){

                sum[0][i] = 0;

            }else{

                sum[0][i] = value[0];

            }

        }

        for(int i = 0; i < num; i++){

            sum[i][0] = 0;

        }

        for(int  i = 1; i < num; i++){

            for(int j = 1; j < bagweigth + 1; j++){

                if(j < weigth[i]){

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

                }else{

                    sum[i][j] = Math.max(sum[i - 1][j],sum[i - 1][j - weigth[i]]+ value[i]);

                }

            }

        }

    }

}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值