01_背包问题

package org.josh;

import java.util.*;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(); // 物品数量
long w = scanner.nextLong(); // 背包容量,使用long防止溢出
int[] v = new int[n]; // 存储每个物品的价值(这里视为重量)
for (int i = 0; i < n; i++) {
v[i] = scanner.nextInt();
}

    // 使用分治法将物品分成两组,分别计算子集和int mid = n / 2; // 将物品数组分为前半部分和后半部分List<Long> sumA = generateSubsetSums(v, 0, mid); // 前半部分的所有子集和List<Long> sumB = generateSubsetSums(v, mid, n); // 后半部分的所有子集和Collections.sort(sumB); // 对后半部分的子集和进行排序,便于后续二分查找long count = 0; // 统计有效子集组合的数量for (long a : sumA) { // 遍历前半部分的每个子集和aif (a > w) continue; // 剪枝:如果当前a已经超过背包容量,跳过long remaining = w - a; // 计算剩余可用容量// 在sumB中找到不大于remaining的元素个数,并累加到countint idx = upperBound(sumB, remaining);count += idx;}System.out.println(count); // 输出结果
}/*** 生成指定区间[start, end)内所有子集的和* @param v 物品数组* @param start 起始索引(包含)* @param end 结束索引(不包含)* @return 所有可能子集的和的列表*/
private static List<Long> generateSubsetSums(int[] v, int start, int end) {List<Long> sums = new ArrayList<>();int n = end - start; // 当前区间的元素个数// 遍历所有可能的子集(通过位掩码表示)for (int mask = 0; mask < (1 << n); mask++) {long sum = 0;// 检查每个位是否被选中,计算对应的子集和for (int i = 0; i < n; i++) {if ((mask & (1 << i)) != 0) { // 第i位被选中sum += v[start + i]; // 将对应物品的价值累加}}sums.add(sum);}return sums;
}/*** 在已排序的列表中查找最后一个小于等于target的元素位置,返回符合条件元素的数量* @param list 已排序的列表* @param target 目标值* @return 列表中不大于target的元素个数*/
private static int upperBound(List<Long> list, long target) {int left = 0, right = list.size() - 1;int res = -1; // 初始化为-1,处理所有元素都大于target的情况while (left <= right) {int mid = (left + right) >>> 1; // 无符号右移防止溢出if (list.get(mid) <= target) {res = mid; // 记录当前位置,并继续向右查找可能的更大值left = mid + 1;} else {right = mid - 1; // 中间值过大,向左查找}}// res是最后一个符合条件的元素索引,返回数量为res+1(索引转个数)return res + 1;
}

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

esp32-idf Linux 环境安装教程

一、提前说明 1. 系统环境 Ubuntu22.04 2. 适配芯片 ESP32S3 3. idf版本 v5.4.1(截止2025年4月13日为最新版本) 二、安装步骤 1. 安装前置依赖 sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev l…

JavaScript 输入输出语句

在JavaScript中&#xff0c;输入和输出是与用户交互的基础。无论是从用户那里获取信息还是向用户展示结果&#xff0c;正确使用输入输出语句都是至关重要的。本文将详细介绍JavaScript中常用的输入输出方法及其应用场景。 一、输出语句 &#xff08;一&#xff09;console.lo…

TCP 如何在网络 “江湖” 立威建交?

一、特点&#xff1a; &#xff08;一&#xff09;面向连接 在进行数据传输之前&#xff0c;TCP 需要在发送方和接收方之间建立一条逻辑连接。这一过程类似于打电话&#xff0c;双方在通话前需要先拨号建立连接。建立连接的过程通过三次握手来完成&#xff0c;确保通信双方都…

文章记单词 | 第29篇(六级)

一&#xff0c;单词释义 AI /ˌeɪ ˈaɪ/ abbr. 人工智能&#xff08;Artificial Intelligence&#xff09;inventory /ˈɪnvəntri/ n. 存货清单&#xff1b;财产清单&#xff1b;库存货物&#xff1b;存货&#xff1b;v. 编制目录&#xff1b;开列清单&#xff1b;盘存cha…

【C#】.NET 8适配器模式实战:用C#实现高可用系统集成与接口桥接艺术

系统集成挑战与适配器模式的价值 当需要整合不同架构或API的系统时&#xff0c;接口兼容性问题往往成为拦路虎。**适配器设计模式&#xff08;Adapter Pattern&#xff09;**通过转换接口形态&#xff0c;完美解决这种不兼容性问题。本文将通过C# .NET 8实战演示适配器模式的基…

Nginx基础到全面掌握高性能Web服务核心

目录 前言 第一部分&#xff1a;Nginx基础入门 1.1 什么是Nginx&#xff1f; 1.2 Nginx的典型应用场景 第二部分&#xff1a;Nginx安装与部署 2.1 在不同操作系统上安装Nginx 2.2 验证安装与基本操作 第三部分&#xff1a;Nginx配置详解 3.1 核心配置文件解析 3.2 虚…

C语言中while的相关题目

一、题目引入 以下程序中,while循环的循环次数是多少次? 二、代码分析 首先要明确的一点 while循环是当循环条件为真 就会一直循环 不会停止 while中i是小于10的 说明i可以取到0 1 2 3 4 5 6 7 8 9 进入第一个if判断i小于1为真时执行continue i0是为真的 执行continue 后…

idea 创建 maven-scala项目

文章目录 idea 创建 maven-scala项目1、创建普通maven项目并且配置pom.xml文件2、修改项目结构1&#xff09;创建scala目录并标记成【源目录】2&#xff09;导入scala环境3&#xff09;测试环境 idea 创建 maven-scala项目 1、创建普通maven项目并且配置pom.xml文件 maven依赖…

微服务之间调用外键“翻译”的方法概述

写在前面的话&#xff1a;减少strean流操作&#xff0c;减少多层嵌套for循环。使用普通for循环和map的方式进行转换&#xff0c; 第一步查询数据 List<Student> findList studentDao.findList(findMap); 第二步准备遍历和赋值 if(CollectionUtil.isNotEmpty(findLis…

Spring Boot 中集成 Disruptor_高性能事件处理框架

1. 引言 1.1 什么是 Disruptor Disruptor 是一个高性能的事件处理框架,广泛应用于金融交易系统、日志记录、消息队列等领域。它通过无锁机制和环形缓冲区(Ring Buffer)实现高效的事件处理,具有极低的延迟和高吞吐量的特点。 1.2 为什么使用 Disruptor 高性能:通过无锁机…

Java中equals与 “==” 的区别

首先我们要掌握基本数据类型和引用类型的概念 基本数据类型&#xff1a; byte&#xff0c;short&#xff0c;int,long,float,double,boolean,char 基本的八大数据类型都各自封装着包装类&#xff0c;提供了更多的方法&#xff0c;并且都是引言类型 引用类型&#xff1a; 引…

青少年编程与数学 02-016 Python数据结构与算法 11课题、分治

青少年编程与数学 02-016 Python数据结构与算法 11课题、分治 一、分治算法的基本原理二、分治算法的实现步骤快速排序算法代码示例&#xff08;Python&#xff09; 三、分治算法的复杂度分析四、分治算法的优缺点优点&#xff1a;缺点&#xff1a; 五、分治算法的应用&#xf…

RFID技术概览

一、RFID技术定义 RFID&#xff08;Radio Frequency Identification&#xff0c;射频识别&#xff09; 是一种通过无线电信号识别目标对象并获取相关数据的非接触式自动识别技术。它利用射频信号的空间耦合&#xff08;电感或电磁耦合&#xff09;实现无物理接触的信息传递与目…

【C++游戏引擎开发】第13篇:光照模型与Phong基础实现

一、Phong模型数学原理 1.1 光照叠加公式 L = k a I a + k d I d max ⁡ ( 0 , n ⋅ l ) + k s I s max ⁡ ( 0 , r ⋅ v ) α L = k_a I_a + k_d I_d \max(0, \mathbf{n} \cdot \mathbf{l}) + k_s I_s \max(0, \mathbf{r} \cdot \mathbf{v})^\alpha L=ka​Ia​+kd​Id​max(0…

C语言中数组与指针:差异、应用及深度剖析

在C语言编程领域中&#xff0c;数组和指针是极为重要的概念&#xff0c;它们各自扮演着独特的角色&#xff0c;既有着紧密的联系&#xff0c;又存在显著的区别。深入理解它们的作用与差异&#xff0c;是掌握C语言编程的关键。 数组&#xff1a;数据的有序集合 数组是一组具有相…

【AI大模型】大模型RAG技术Langchain4j 核心组件深入详解

目录 一、前言 二、Langchain4j概述 2.1 Langchain4j 是什么 2.2 Langchain4j 主要特点 2.3 Langchain4j 核心组件 2.4 Langchain4j 核心优势 三、Langchanin4j组件应用实战 3.1 前置准备 3.1.1 导入如下依赖 3.1.2 获取apikey 3.1.3 获取官方文档 3.2 聊天组件 3.…

Web渗透之文件包含漏洞

文件包含漏洞原理 1、源代码 <?php$filename $_GET[filename]; include $filename; //或include_once,require,require_onceecho "欢迎来到PHP的世界.";?> 2、利用条件 php.ini中alllow_url_fopenOn(默认开启)和allow_url_includeOff(默认关闭)要开启…

MySQL 中查询 VARCHAR 类型 JSON 数据的

在数据库设计中&#xff0c;有时我们会将 JSON 数据存储在 VARCHAR 或 TEXT 类型字段中。这种方式虽然灵活&#xff0c;但在查询时需要特别注意。本文将详细介绍如何在 MySQL 中有效查询存储为 VARCHAR 类型的 JSON 数据。 一、问题背景 当 JSON 数据存储在 VARCHAR 列中时&a…

路由器开启QOS和UPNP的作用

QOS 的作用 保障关键业务带宽&#xff1a;可根据网络应用的重要性分配带宽。比如在家庭网络中&#xff0c;当多人同时使用网络时&#xff0c;将视频会议等实时性要求高的关键业务设置为高优先级&#xff0c;确保其能获得足够带宽&#xff0c;避免卡顿&#xff0c;而文件下载等…

5G网络下客户端数据业务掉线频繁

MCPTT&#xff08;Mission Critical Push-to-Talk&#xff09;客户端的日志&#xff0c;和界面在待机状态下&#xff08;即没有做通话等业务操作&#xff09;&#xff0c;会频繁提示“离线”。 主要先看有没有丢网&#xff0c;UL BLER有没有问题。确认没有问题。看到业务信道释…