蓝桥杯 -- 0-1背包 完全背包java

0-1背包以及完全背包

蓝桥杯对应题目

https://www.lanqiao.cn/problems/1174/learning/

https://www.lanqiao.cn/problems/1175/learning/

0-1背包题目描述

小明有一个容量为 VV 的背包。

这天他去商场购物,商场一共有 NN 件物品,第 ii 件物品的体积为 w_iw**i,价值为 v_iv**i

小明想知道在购买的物品总体积不超过 VV 的情况下所能获得的最大价值为多少,请你帮他算算。

输入描述

输入第 11 行包含两个正整数 N,VN,V,表示商场物品的数量和小明的背包容量。

第 2\sim N+12∼N+1 行包含 22 个正整数 w,vw,v,表示物品的体积和价值。

1\leq N\leq10^21≤N≤102,1\leq V \leq 10^31≤V≤103,1 \leq w_i,v_i \leq10^31≤w**i,v**i≤103。

输出描述

输出一行整数表示小明所能获得的最大价值。

输入输出样例

示例 1

输入

5 20
1 6
2 5
3 8
5 15
3 3 

输出

37

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

完全背包题目描述

小明有一个容量为 VV 的背包。

这天他去商场购物,商场一共有 NN 种物品,第 ii 种物品的体积为 w_iw**i,价值为 v_iv**i,每种物品都有无限多个。

小明想知道在购买的物品总体积不超过 VV 的情况下所能获得的最大价值为多少,请你帮他算算。

输入描述

输入第 11 行包含两个正整数 N,VN,V,表示商场物品的数量和小明的背包容量。

第 2\sim N+12∼N+1 行包含 22 个正整数 w,vw,v,表示物品的体积和价值。

1\leq N\leq10^31≤N≤103,1\leq V \leq 10^31≤V≤103,1 \leq w_i,v_i \leq10^31≤w**i,v**i≤103。

输出描述

输出一行整数表示小明所能获得的最大价值。

输入输出样例

示例 1

输入

5 20
1 6
2 5
3 8
5 15
3 3 

输出

120

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

题解

使用一维数组

注意0-1背包要从大往小遍历 避免一个物品添加多次

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改


public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int V = scan.nextInt();
        int[] weight = new int[N];
        int[] value = new int[N];
        for(int i = 0; i < N; i++){
    
    
          weight[i] = scan.nextInt();
          value[i] = scan.nextInt();
        }
        //一维滚动数组
        int[] dp =  new int[V+1];
        for(int i = 0; i < N; i++){
    
    
          for(int j = V; j >= weight[i]; j--){
    
    
            dp[j] = Math.max(dp[j],dp[j-weight[i]] + value[i]);
          }
        }
        System.out.println(dp[V]);
        //在此输入您的代码...
        scan.close();
    }
}

而完全背包唯一不同就是内层循环的遍历方向是从小到大

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        int V = scan.nextInt();
        int[] weight = new int[N];
        int[] value = new int[N];
        for(int i = 0; i < N; i++){
    
    
          weight[i] = scan.nextInt();
          value[i] = scan.nextInt();
        }
        //一维滚动数组
        int[] dp =  new int[V+1];
        for(int i = 0; i < N; i++){
    
    
          for(int j = weight[i]; j <= V; j++){
    
    
            dp[j] = Math.max(dp[j],dp[j-weight[i]] + value[i]);
          }
        }
        System.out.println(dp[V]);
        //在此输入您的代码...
        scan.close();
    }
}

另外注意,使用一维滚动数组必须外层遍历物品,内层遍历背包容量

猜你喜欢

转载自blog.csdn.net/weixin_51712663/article/details/127337594