蓝桥杯真题——01背包问题(java详解)

目录

01背包问题例题引入

蓝桥杯国赛真题

蓝桥杯2195题.费用报销

蓝桥杯2201题.搬砖


01背包问题和最值问题离不开,最值问题嘛,就又和动态规划离不开,大家不太了解动态规划的可以看我之前写的文章,基础版里面有动态规划的模板。

动态规划算法详解基础篇-CSDN博客

动态规划算法详解进阶篇-CSDN博客

01背包问题例题引入

有 N 件物品和一个容量是 V 的背包。每种物品只有一件。

第 i 件物品的体积是 V[i],价值是 W[i]。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大,输出最大价值。

/*

1、定义dp含义: dp[i][v]: 在0...i中,体积为v的背包中能够拿到的最大价值为dp[i][v]

2、关系式: dp[i][v] = ?
         
       1) 对于第i件物品,如果我们决定不把它放进背包里,那么就是dp[i - 1][v]
       2) 对于第i件物品,如果我们把它放进背包里,那么就是dp[i - 1][v - w[i]] + v
  
   综合起来就是 dp[i][v] = Math.max(dp[i - 1][v], dp[i - 1][v - w[i]] + v);

3、初始化条件:dp[0][v] = 0;   dp[i][0] = 0;

*/

import java.util.Scanner;
public class Bag {
    public static void main(String[]args){
        Scanner scan = new Scanner(System.in);
        //物品数量
        int N = scan.nextInt();
        //背包容量
        int V = scan.nextInt();
        //第i个元素表示第i个物品的体积
        int[]v = new int[N + 1];
        //第i个元素表示第i个物品的价值
        int[]w = new int[N + 1];
        for(int i = 1; i <= N; i++){
            //接下来有N行,每行有两个整数v[i],w[i]
            v[i] = scan.nextInt();
            w[i] = scan.nextInt();
        }
        scan.close();
        //核心代码
       int[][]dp = new int[N + 1][V + 1];
       /*
       这个双层for循环的j表示背包的容量。
       在这个循环中,我们遍历了所有可能的背包容量(从0到V),然后根据当前物品的体积和价值来更新dp数组。
       具体来说,对于每个物品i和背包容量j,我们有以下两种情况:
       如果当前物品的体积大于背包容量j,那么我们不能将这个物品放入背包,
       所以dp[i][j] = dp[i-1][j],即不选择当前物品的最大价值。
       如果当前物品的体积小于等于背包容量j,那么我们可以选择是否将这个物品放入背包。
       如果我们选择放入背包,那么背包的剩余容量为j - v[i],此时的最大价值为dp[i-1][j-v[i]] + w[i];
       如果我们选择不放入背包,那么背包的最大价值为dp[i-1][j]。我们需要在这两种情况下选择一个最大值作为dp[i][j]的值。
       */
       for(int i = 1; i <= N; i++){
           for(int j = 0; j <= V; j++){
               if(v[i] > j){
                   dp[i][j] = dp[i - 1][j];
               }
               else{
                   dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);
               }
           }
           System.out.println(dp[N][V]);
       }
    }
}

蓝桥杯国赛真题

蓝桥杯历年真题中有5道关于背包问题的,其中01背包问题占两道。

蓝桥杯2195题.费用报销

3.费用报销 - 蓝桥云课 (lanqiao.cn)

题解:

代码定义了一些变量和数组,包括一个StreamTokenizer对象用于读取输入,一个二维数组input用于存储每个任务的开始时间和所需时间,一个二维布尔数组dp用于存储每个任务是否可以在给定的时间内完成,以及一些常量N和M。

在run()方法中,首先读取输入的任务数量n、最大天数m和最小间隔k。然后,对于每个任务,读取其开始时间和所需时间,并将其存储在input数组中。接着,使用自定义的比较器MyComparator对input数组进行排序,以便按照任务的开始时间进行排序。

接下来,初始化dp数组的第一行和第一列为true,表示没有任务时也可以完成0个任务。然后,遍历每个任务,对于每个任务,找到在其开始时间之前且结束时间与当前任务开始时间之差大于等于k的任务,更新dp数组。最后,找到dp数组最后一列的最大值,即为最多可以完成的任务数量。

最后,输出最多可以完成的任务数量。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;
import java.util.Comparator;

public class Test1 {
    public static void main(String[] args) {
        new Test1().run();
    }
    StreamTokenizer streamTokenizer = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    int nextInt() {
        try {
            streamTokenizer.nextToken();
        } catch (IOException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        return (int)streamTokenizer.nval;
    }
    int N = 1010, M = 5010;
    int[] days = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int[][] input = new int[N][2];
    boolean[][] dp = new boolean[N][M];
    void run() {
        int n = nextInt(), m = nextInt(), k = nextInt();
        for(int i = 1; i <= 12; i++) {
            days[i] += days[i - 1];
        }
        for(int i = 1; i <= n; i++) {
            input[i][0] = days[nextInt() - 1] + nextInt();
            input[i][1] = nextInt();
        }
        Arrays.sort(input, 1, n + 1, new MyComparator());
        dp[0][0] = true;
        int l = 0, max = 0;
        for(int i = 1; i <= n; i++) {
            while(input[i][0] - input[l + 1][0] >= k) l++;
            for(int j = 0; j <= m; j++) {
                dp[i][j] = dp[i - 1][j];
                if(j >= input[i][1] && dp[l][j - input[i][1]]) {
                    dp[i][j] = true;
                    max = Math.max(max, j);
                }
            }
        }
        System.out.println(max);
    }
    
    class MyComparator implements Comparator<int[]>{

        @Override
        public int compare(int[] o1, int[] o2) {
            // TODO 自动生成的方法存根
            return o1[0] - o2[0];
        }    
        
    }
 }

蓝桥杯2201题.搬砖

4.搬砖 - 蓝桥云课 (lanqiao.cn)

 

题解: 

  1. 首先,从标准输入读取物品的数量n,然后读取每个物品的价值和重量。同时,计算所有物品的总价值。

  2. 然后,使用自定义的比较器对物品进行排序。这个比较器基于一个规则:如果物品i的价值加上重量大于物品j的价值减去重量,那么物品i应该排在物品j之前。这个规则用于确定如何选择物品以最大化总价值。

  3. 初始化一个动态规划数组dp,其中dp[j]表示总重量不超过j时可以获得的最大价值。初始时,dp数组的所有元素都为0。

  4. 对于每个物品,从总价值开始向下遍历到物品的重量。如果当前的重量减去物品的重量小于等于物品的价值,那么就可以选择这个物品。在这种情况下,dp[j]的值应该是dp[j]和dp[j - arr[i][0]] + arr[i][1]中的较大值。这是因为我们可以选择这个物品,所以总价值会增加arr[i][1],而总重量会减少arr[i][0]。

  5. 在每次更新dp[j]后,都会检查并更新最大价值ans。

  6. 最后,输出最大价值ans。 

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Test1 {
    
    public static void main(String[] args) {
        new Test1().run();
    }
    int W = 20010, N = 1010, n;
    int[] dp = new int[W];
    int[][] arr = new int[N][2];
    int sum = 0;
    void run() {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        for(int i = 1; i <= n; i++) {
            arr[i][0] = sc.nextInt();
            arr[i][1] = sc.nextInt();
            sum += arr[i][0];
        }
        sc.close();
        Arrays.sort(arr, 1, n + 1, new Comparator<int[]>() {
            //规律: vi - wj > vj - wi -> vi + wi > vj + wj
            @Override
            public int compare(int[] o1, int[] o2) {
                // TODO Auto-generated method stub
                return o1[0] + o1[1] - o2[0] - o2[1];
            }
        });
        int ans = 0;
        for(int i = 1; i <= n; i++) {
            for(int j = sum; j >= arr[i][0]; j--) {
                if(j - arr[i][0] <= arr[i][1]) {
                    dp[j] = Math.max(dp[j], dp[j - arr[i][0]] + arr[i][1]);
                }
                ans = Math.max(ans, dp[j]);
            }
        }
        System.out.println(ans);
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/247601.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

中文字符串逆序输出

今天碰到这个题&#xff0c;让我逆序输出中文字符串&#xff0c;可给我烦死了&#xff0c;之前没有遇到过&#xff0c;也是查了资料才知道&#xff0c;让我太汗颜了。 英文字符串逆序输出很容易&#xff0c;开辟一块空间用来存放逆序后的字符串&#xff0c;从后往前遍历原字符串…

西南交通大学【数电实验8---外星萤火虫设计】

一、实验电路图、状态图、程序代码、仿真代码、仿真波形图&#xff08;可以只写出核心功能代码&#xff0c;代码要有注释&#xff09; 代码文件 激励文件 Modelsim仿真 二、引脚分配表&#xff08;电路中的信号名称->主板器件名称->引脚号PIN&#xff09; 信号名 主板器…

【C++初阶】类与对象(上)

类与对象&#xff08;上&#xff09; 1.面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符及封装4.1 访问限定符4.2 封装 5.类的作用域6.类的实例化7.类对象模型7.1 如何计算类对象的大小7.2 结构体内存对齐规则 8.this指针8.1 this指针的引出8.2 this指针的特性…

微软microsoft推出了最新的小型但强大的开源语言AI模型Phi-2

微软推出了最新的小型开源语言模型 Phi-2。该模型只有 27 亿个参数&#xff0c;却能超过比它大 25 倍的模型的性能。Phi-2 是微软 Phi 项目的一部分&#xff0c;旨在制作小而强大的语言模型。该项目包括 13 亿参数的 Phi-1&#xff0c;据称在 Python 编码方面实现了最先进的性能…

如何使用mysql去除表中重复的字段

简介&#xff1a; 此处的建表题目来自我们的也门哥Maged&#xff0c;非常感谢他出的这些测试题目&#xff0c;让我能够独立思考&#xff0c;反复试去找到cw2的正确做法。 数据库准备&#xff1a; 害怕被好homi被刺然后被 academic warning 所以浅浅打个码。 创建好这张表后我…

ipad协议限制号版

特别声明&#xff1a;仅供学习交流 Applet显示/隐藏显示操作展开操作 POST /api/Applet/GetRandomAvatar 提取一个随机昵称和照片 POST /api/Applet/UploadAvatarImg 上传小程序身份照片 POST /api/Applet/AddAvatar 增加一个小程序身份 POST /api/Applet/OauthSdkApp 授权A…

ShellCode注入程序

程序功能是利用NtQueueApcThreadEx注入ShellCode到一个进程中&#xff0c;程序运行后会让你选择模式&#xff0c;按1为普通模式&#xff0c;所需的常规API接口都是使用Windows原本正常的API&#xff1b;在有游戏保护的进程中Windows原本正常的API无法使用&#xff0c;这时候需要…

绘图示例---QT手动调用绘图事件,按钮控制图片

效果&#xff1a; 点击 “移动” 图片向右移动20&#xff0c;点击 “西理win嘛” 图片每秒向右移动20 QQ录屏20231212164128 下面时代码详解&#xff1a; 注意使用UI和代码实现按钮的不同 UI: ui->pushButton->setGeometry(windowWidth-105, windowHeight-25, 100, 20);…

ChatGPT 也宕机了?如何预防 DDOS 攻击的发生

最近&#xff0c;开发人工智能聊天机器人的公司 OpenAI 遭受了一次规模较大的分布式拒绝服务&#xff08;DDoS&#xff09;攻击&#xff0c;导致其旗下的 ChatGPT 服务在短短 12 小时内遭遇了 4 次断网&#xff0c;众多用户遭受了连接失败的问题。 这次攻击事件引起了广泛的关…

C++ stringOJ练习题

目录 把字符串转换成整数 反转字符串 字符串中的第一个唯一字符 字符串最后一个单词的长度 找出字符串中第一个只出现一次的字符 字符串相加 字符串最后一个单词长度 字符串相乘 反转字符串3 反转字符串2 验证回文串 把字符串转换成整数 通过遍历字符串并逐位转换…

漏洞复现-浙大恩特客户资源管理系统CustomerAction.entphone;.js 接口任意文件上传漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

【开发工具】最新VMWare无法识别USB设备,驱动错误,未知错误【2023.12.15】

解决方案1&#xff1a;在这里改下连接方式 多试试 解决方案2 控制面板卸载程序&#xff0c;进行VMWare的修复 解决方案3 对于Windows7系统&#xff0c;切换解决方案1的usb类型为3.1&#xff0c;并下载这个intel的驱动包到虚拟机里 https://www.intel.com/content/www/us/en/do…

毅速:金属3D打印引领制造业进入新时代

随着科技的飞速发展&#xff0c;3D打印技术逐渐渗透到各个领域&#xff0c;为制造业带来了革命性的变革。其中&#xff0c;金属3D打印技术以其独特的优势&#xff0c;正逐渐成为制造业的新宠。 金属3D打印&#xff0c;也称为金属粉末烧结&#xff0c;是一种利用高能激光束将金属…

【JUC】三十、什么是AQS

文章目录 0、背景1、AQS介绍2、AQS核心概念3、AQS是JUC的基石4、锁和同步器的关系5、AQS的作用6、state和CLH队列6、AQS的内部类Node 0、背景 一段常见的代码&#xff1a; Lock lock new ReentrantLock(); lock.lock; try{//do Something } finally{lock.unlock(); }简单的一…

10分钟利用宝塔面板在阿里云服务器部署个人网页

目录 1、申请阿里云服务器 2、更换镜像&#xff08;可选&#xff09; 3、远程链接阿里云服务器安装宝塔面板 4、开放安全组 5、宝塔面板上传项目文件 1、申请阿里云服务器 购买链接->阿里云服务器购买 个人购买的就是这款&#xff0c;比较经济合算&#xff0c;而且2核…

HTTP 404错误:页面未找到,如何解决

在互联网上浏览时&#xff0c;偶尔会遇到“HTTP 404错误&#xff1a;页面未找到”的提示。这通常意味着用户尝试访问的网页不存在或无法找到。本文将探讨HTTP 404错误的原因以及如何解决这个问题。 一、HTTP 404错误的原因 HTTP 404错误可能是由多种原因引起的。以下是一些常…

线程安全集合类

文章目录 1. ConcurrentHashMap2. LinkedBlockingQueue 阻塞队列3. ConcurrentLinkedQueue4. CopyOnWriteArrayList JDK1.7 hashmap采用数组加链表头插的方式&#xff0c;在扩容时会出现循环死链问题&#xff0c;A->B->C扩容后C->B->A AB BA出现循环死链。 1. Conc…

《opencv实用探索·十九》光流法检测运动目标

前言 光流法&#xff08;Optical Flow&#xff09;是计算机视觉中的一种技术&#xff0c;用于估计图像中相邻帧之间的像素位移或运动。它是一种用于追踪图像中物体运动的技术&#xff0c;可以在视频中检测并测量物体的运动轨迹。 光流的直观理解&#xff1a; 光流是一个视频中两…

ubuntu-c++-可执行模块-动态链接库-链接库搜索-基础知识

文章目录 1.动态链接库简介2.动态库搜索路径3.运行时链接及搜索顺序4.查看可运行模块的链接库5.总结 1.动态链接库简介 动态库又叫动态链接库&#xff0c;是程序运行的时候加载的库&#xff0c;当动态链接库正确安装后&#xff0c;所有的程序都可以使用动态库来运行程序。动态…

upload-labs笔记

简介 upload-labs是一个使用php语言编写的&#xff0c;专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共21关&#xff0c;每一关都包含着不同上传方式。 文件上传漏洞是指&#xff1a; Web 服务器允许用户将文件上传至其…