当前位置: 首页 > article >正文

背包问题——动态规划的经典问题包括01背包问题和完全背包问题

        01背包问题:给你多个物品每个物品只能选一次,要你在不超过背包容积(或者恰好等于)的情况下选择装价值最大的组合。如果没有动态规划的基础其实是很难理解这个问题的,所以看这篇文章之前先去学习一下动态规划的基本思想。

        对于这个问题我们先定义状态表示:dp[i][j]表示在1到i个物品中选择容积不超过j(或者恰好等于j)的最大价值(我们的下标从1开始,所以对于题目给的数组我们一般需要头插一个不影响后面填表的数一般就是0)

        推导状态转移方程:

                对于第i个物品我们其实有两种选择,一种是不选,一种就是选。

                当我们不选择第i个物品时,那么对于在1到i个物品中选择容积不超过j(等于j)的最大价值的物品其实是和从1到i-1个物品中选择容积不超过j(等于j)的最大价值的物品。

                当我们选择第i个物品那么首先我们需要判断的就是我们的容积j必须大于等于(等于,并且我们的dp[i-1][j-v[i]]必须要有意义,比如我们在初始化时规定-1是没有意义的那么我们不仅要保证j>=v[i] && dp[i-1][j-v[i]] != -1)我们的第i个物品的体积,然后我们的dp[i][j]其实就和我们在前i-1个物品中选择容积为j-v[i]的最大价值加上我们的第i个物品的价值。

        初始化这里有视情况而定。

        填表一般就是从上往下,从左往右,这里说的是未优化版本,如果我们进行优化那么就要判断到底是从左往右还是从右往左。

        背包问题的优化一般很简单,就是通过滚动数组来实现,我们在代码上的体现就是删掉i的哪一维,然后改变一下填表顺序就可以了。

        下面来一道题:【模板】01背包_牛客题霸_牛客网

我这里提供两种版本一种是未优化的,一种是优化的

//未优化版本
#include<iostream>using namespace std;const int N = 1010;int n,V,v[N],w[N];
int dp[N][N];int main()
{int ret1 = 0;cin>>n>>V;for(int i = 1;i<=n;i++) cin>>v[i]>>w[i];for(int i = 1;i<=n;i++)for(int j = 1;j<=V;j++){dp[i][j] = dp[i-1][j];if(j>=v[i]) dp[i][j] = max(dp[i][j],dp[i-1][j-v[i]]+w[i]);ret1 = max(ret1,dp[i][j]);}cout<<ret1<<endl;//第二问的初始化for(int i = 1;i<=V;i++) dp[0][i] = -1;int ret2 = -1;for(int i = 1;i<=n;i++)for(int j = 1;j<=V;j++){dp[i][j] = dp[i-1][j];if(j>=v[i] && (dp[i-1][j-v[i]] != -1))dp[i][j] = max(dp[i][j],dp[i-1][j-v[i]]+w[i]);}for(int i = 1;i<=n;i++) ret2 = max(ret2,dp[i][V]);if(ret2 == -1) cout<<0<<endl;else cout<<ret2<<endl;return 0;
}
//优化版本
#include<iostream>using namespace std;const int N = 1010;int n,V,v[N],w[N];
int dp[N];int main()
{int ret1 = 0;cin>>n>>V;for(int i = 1;i<=n;i++) cin>>v[i]>>w[i];for(int i = 1;i<=n;i++)for(int j = V;j>=v[i];j--){dp[j] = max(dp[j],dp[j-v[i]]+w[i]);ret1 = max(ret1,dp[j]);}cout<<ret1<<endl;//第二问的初始化for(int i = 1;i<=V;i++) dp[i] = -1;int ret2 = -1;for(int i = 1;i<=n;i++)for(int j = V;j>=v[i];j--){if((dp[j-v[i]] != -1))dp[j] = max(dp[j],dp[j-v[i]]+w[i]);}for(int i = 1;i<=n;i++) ret2 = max(ret2,dp[V]);if(ret2 == -1) cout<<0<<endl;else cout<<ret2<<endl;return 0;
}

        完全背包问题:与上面的01背包问题的不同在与这类问题中我们的同一个物品是可以选择无数个的,那么我们的状态转移方程选择第i个物品的时候就不可以沿用01背包的状态转移方程,因为这里有点麻烦我就放图片了

        

        通过这一过程我们发现其实dp[i][j]是等于max(dp[i-1][j],dp[i][j-v[i]]+w[i])的但是对于dp[i][j-v[i]]这个地方我们需要先判断有没有意义,才能进行后续的填值。

        做个题目:【模板】完全背包_牛客题霸_牛客网

依旧提供两个版本:
        我提供的第一个版本里的dp[i][j]选择第i个物品时有两种写法一种是循环一种是我的图片那种方式,但是都不会超时最后用数学的那种是因为美观

//未优化版本
#include<iostream>
#include<vector>int max(int x,int y) {return x>y?x:y;}int main()
{int n,V;std::cin>>n>>V;std::vector<int> v(n),w(n);for(int i = 0;i<n;i++) std::cin>>v[i]>>w[i];std::vector<std::vector<int>> dp(n+1,std::vector<int>(V+1));v.insert(v.begin(),0),w.insert(w.begin(),0); int _max = 0;for(int i = 1;i<=n;i++)for(int j = 1;j<=V;j++){dp[i][j] = dp[i-1][j];// int val = 1;// for(int k = v[i];k<=j;k+=v[i])// {//     dp[i][j] = max(dp[i][j],dp[i-1][j-val*v[i]]+val*w[i]);//     val++;// }if(j>=v[i]) dp[i][j] = max(dp[i][j],dp[i][j-v[i]]+w[i]);_max = max(_max,dp[i][j]);}std::cout<<_max<<std::endl;for(int i = 0;i<=n;i++) dp[i].clear();for(int i = 1;i<=V;i++) dp[0][i] = -1;for(int i = 1;i<=n;i++)for(int j = 1;j<=V;j++){dp[i][j] = dp[i-1][j];// int val = 1;// for(int k = v[i];k<=j;k+=v[i])// {//     if(dp[i-1][j-val*v[i]] != -1)//         dp[i][j] = max(dp[i][j],dp[i-1][j-val*v[i]]+w[i]*val);//     val++;// }if(j>=v[i] && dp[i][j-v[i]] != -1) dp[i][j] = max(dp[i][j],dp[i][j-v[i]]+w[i]);}if(dp[n][V] != -1) std::cout<<dp[n][V]<<std::endl;else std::cout<<"0"<<std::endl;return 0;
}
#include<iostream>
#include<vector>int max(int x,int y) {return x>y?x:y;}int main()
{int n,V;std::cin>>n>>V;std::vector<int> v(n),w(n);for(int i = 0;i<n;i++) std::cin>>v[i]>>w[i];std::vector<int> dp(V+1);v.insert(v.begin(),0),w.insert(w.begin(),0); int _max = 0;for(int i = 1;i<=n;i++)for(int j = v[i];j<=V;j++){// int val = 1;// for(int k = v[i];k<=j;k+=v[i])// {//     dp[j] = max(dp[j],dp[j-val*v[i]]+val*w[i]);//     val++;// }if(j>=v[i]) dp[j] = max(dp[j],dp[j-v[i]]+w[i]);_max = max(_max,dp[j]);}std::cout<<_max<<std::endl;dp.clear();for(int i = 1;i<=V;i++) dp[i] = -1;for(int i = 1;i<=n;i++)for(int j = v[i];j<=V;j++){// int val = 1;// for(int k = v[i];k<=j;k+=v[i])// {//     if(dp[j-val*v[i]] != -1)//         dp[j] = max(dp[j],dp[j-val*v[i]]+w[i]*val);//     val++;// }if(j>=v[i] && dp[j-v[i]] != -1) dp[j] = max(dp[j],dp[j-v[i]]+w[i]);}if(dp[V] != -1) std::cout<<dp[V]<<std::endl;else std::cout<<"0"<<std::endl;return 0;
}

        

相关文章:

背包问题——动态规划的经典问题包括01背包问题和完全背包问题

01背包问题&#xff1a;给你多个物品每个物品只能选一次&#xff0c;要你在不超过背包容积&#xff08;或者恰好等于&#xff09;的情况下选择装价值最大的组合。如果没有动态规划的基础其实是很难理解这个问题的&#xff0c;所以看这篇文章之前先去学习一下动态规划的基本思想…...

MyBatis 面试专题

MyBatis 面试专题 基础概念MyBatis中的工作原理MyBatis 与 Hibernate 的区别&#xff1f;#{} 和 ${} 的区别&#xff1f;MyBatis 的核心组件有哪些&#xff1f; 映射与配置如何传递多个参数&#xff1f;ResultMap 的作用是什么&#xff1f;动态 SQL 常用标签有哪些&#xff1f;…...

Animation - AI Controller控制SKM_Manny的一些问题

一些学习笔记归档&#xff1b; 在UE5中&#xff0c;使用新的小白人骨骼&#xff1a;SKM_Manny&#xff0c;会跟UE4中的小白人有一些差别&#xff1b; 比如在用AI Controller控制使用该骨骼&#xff08;配置默认的ABP_Manny Animation BP&#xff09;角色的时候&#xff0c;需要…...

安科瑞新能源防逆流解决方案:守护电网安全,赋能绿色能源利用

随着光伏、储能等新能源在用户侧的快速普及&#xff0c;如何避免电力逆流对电网造成冲击&#xff0c;成为行业关注的焦点。安科瑞凭借技术实力与丰富的产品矩阵&#xff0c;推出多场景新能源防逆流解决方案&#xff0c;以智能化手段助力用户实现安全、经济的能源管理&#xff0…...

filebeat和logstash区别

Filebeat 角色: 轻量级日志收集器。 功能: 从指定的日志文件中读取日志数据。 可以从多个源&#xff08;如文件、系统日志、容器日志等&#xff09;收集日志。 将收集到的日志数据传输到 Logstash、Elasticsearch 或其他支持的输出端点。 性能: 由于是轻量级的&#xff0c;File…...

【一起学Rust | Tauri2.0框架】基于 Rust 与 Tauri 2.0 框架实现全局状态管理

前言 在现代应用程序开发中&#xff0c;状态管理是构建复杂且可维护应用的关键。随着应用程序规模的增长&#xff0c;组件之间共享和同步状态变得越来越具有挑战性。如果处理不当&#xff0c;状态管理可能会导致代码混乱、难以调试&#xff0c;并最终影响应用程序的性能和可扩…...

扩散模型算法实战——三维重建的应用

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​ ​​​​​​ ​ ​ 1. 引言 三维重建是计算机视觉和图形学中的一个重要研究方向&#xff0c;旨在从二维图像或其他传感器数据中恢复…...

社群经济4.0时代:开源链动模式与AI技术驱动的电商生态重构

摘要&#xff1a;在Web3.0技术浪潮与私域流量红利的双重驱动下&#xff0c;电商行业正经历从"流量收割"到"用户深耕"的范式转变。本文基于社群经济理论框架&#xff0c;结合"开源链动21模式"、AI智能名片、S2B2C商城小程序源码等创新工具&#x…...

【Linux系统】进程等待:告别僵尸进程深入理解Linux进程同步的核心密码

Linux系列 文章目录 Linux系列前言一、进程等待的核心目的二、进程等待的实现方式2.1 wait()函数2.2 waitpid&#xff08;&#xff09;函数 总结 前言 在Linux系统中&#xff0c;进程等待&#xff08;Process Waiting&#xff09;是多进程编程中的核心机制&#xff0c;指父进程…...

根据文件名称查询文件所在位置

在 Linux 中&#xff0c;根据文件名称查询文件所在位置主要通过命令行工具实现&#xff0c;以下是几种常用方法&#xff1a; --- ### **1. 使用 find 命令&#xff08;最灵活&#xff09;** find 命令可以递归搜索指定目录下的文件&#xff0c;支持按名称、类型、时间等条件过…...

六十天前端强化训练之第二十五天之组件生命周期大师级详解(Vue3 Composition API 版)

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 一、生命周期核心知识 1.1 生命周期全景图 1.2 生命周期钩子详解 1.2.1 初始化阶段 1.2.2 挂载阶段 1.2.3 更新阶段 1.2.4 卸载阶段 1.3 生命周期执行顺序 1.4 父子组…...

Pytorch使用手册(专题五十)—自定义运算符

1. PyTorch 自定义运算符 PyTorch 提供了一个庞大的运算符库,这些运算符可以对张量进行操作(例如 torch.add、torch.sum 等)。然而,您可能希望向 PyTorch 引入一个新的自定义操作,并使其能够与诸如 torch.compile、autograd 和 torch.vmap 等子系统协同工作。为此,您必须…...

springboot整合mybatis-plus(保姆教学) 及搭建项目

一、Spring整合MyBatis (1)将MyBatis的DataSource交给Spring IoC容器创建并管理&#xff0c;使用第三方数据库连接池(Druid&#xff0c;C3P0等)代替MyBatis内置的数据库连接池 (2)将MyBatis的SqlSessionFactory交给Spring IoC容器创建并管理&#xff0c;使用spring-mybatis整…...

VSCode创建VUE项目(三)使用axios调用后台服务

1. 安装axios,执行命令 npm install axios 2. 在 main.ts 中引入并全局挂载 Axios 实例 修改后的 代码&#xff08;也可以单独建一个页面处理Axios相关信息等&#xff0c;然后全局进行挂载&#xff09; import { createApp } from vue import App from ./App.vue import rou…...

JVM常用垃圾回收器

Serial 和Serial Old收集器 Serial 系列的垃圾收集器采用了简单高效、资源消耗最少、单线程收集的设计思路。 简单高效&#xff1a;由于硬件资源有限&#xff0c;垃圾回收器需要设计得简单高效&#xff0c;以减少系统资源的占用。Serial 系列的垃圾收集器实现简单&#xff0c…...

车辆模型——运动学模型

文章目录 约束及系统移动机器人运动学模型&#xff08;Kinematic Model&#xff09;自行车模型含有加速度 a a a 的自行车模型系统偏差模型 在机器人的研究领域中&#xff0c;移动机器人的系统建模与分析是极为关键的基础环节&#xff0c;本文以非完整约束的轮式移动机器人为研…...

EJS缓存解决多页面相同闪动问题

基于 EJS 的模板引擎特性及其缓存机制&#xff0c;以下是关于缓存相同模块的详细解答&#xff1a; 一、EJS 缓存机制的核心能力 模板编译缓存 EJS 默认会将编译后的模板函数缓存在内存中&#xff0c;当相同模板文件被多次渲染时&#xff0c;会直接复用已编译的模板函数&#x…...

<details>和<summary>标签的用途,如何使用它们实现可折叠内容

大白话和标签的用途&#xff0c;如何使用它们实现可折叠内容 <details> 和 <summary> 标签用途 <details> 和 <summary> 标签是 HTML 里的实用标签&#xff0c;二者配合能创建出可折叠内容。 <details> 标签就像是一个容器&#xff0c;能把那…...

HUGO介绍、安装、以及使用

HUGO官方网站&#xff0c;文章内容的简介大部分来自官网的翻译&#xff0c;官网是纯英文描述&#xff0c;英语好的可以前往官方网站&#xff0c;博主在这里简介中简单翻译处理包括一些链接的引用&#xff0c;主要是讲解一下如何安装和使用。 这里再粘贴一个三方网站opendocs.i…...

【STM32实物】基于STM32的太阳能充电宝设计

基于STM32的太阳能充电宝设计 演示视频: 基于STM32的太阳能充电宝设计 硬件组成: 系统硬件包括主控 STM32F103C8T6、0.96 OLED 显示屏、蜂鸣器、电源自锁开关、温度传感器 DS18B20、继电器、5 V DC 升压模块 、TB4056、18650锂电池、9 V太阳能板、稳压降压 5 V三极管。 功能…...

【Netty】长连接与短连接的不同实现

长连接与短连接的不同实现 配置层面 // 长连接配置 bootstrap.option(ChannelOption.SO_KEEPALIVE, true) // 启用 TCP keepalive.option(ChannelOption.TCP_NODELAY, true); // 禁用 Nagle 算法// 短连接不需要这些配置心跳机制 // 长连接需要心跳 pipeline.addLast(new Idl…...

安装 OpenSSL 1.1.1 的完整脚本适用于 Ubuntu 22.04 系统

#!/bin/bash # 更新系统包 sudo apt-get update # 安装编译工具和依赖库 sudo apt-get install -y build-essential checkinstall zlib1g-dev # 下载 OpenSSL 1.1.1 源码 wget https://www.openssl.org/source/openssl-1.1.1.tar.gz # 检查下载是否成功 if [ $? -ne 0 ]; …...

24-智慧旅游系统(协同过滤算法)

介绍 技术&#xff1a; 基于 B/S 架构 SpringBootMySQLLayuivue 环境&#xff1a; Idea mysql maven jdk1.8 管理端功能 管理端主要用于对系统内的各类旅游资源进行管理&#xff0c;包括用户信息、旅游路线、车票、景点、酒店、美食、论坛等内容。具体功能如下&#xff1a; …...

Vue 中的日期格式化实践:从原生 Date 到可视化展示!!!

&#x1f4c5; Vue 中的日期格式化实践&#xff1a;从原生 Date 到可视化展示 &#x1f680; 在数据可视化场景中&#xff0c;日期时间的格式化显示是一个高频需求。本文将以一个邀请码关系树组件为例&#xff0c;深入解析 Vue 中日期格式化的 核心方法、性能优化 和 最佳实践…...

2025年使用Scrapy和Playwright解决网页抓取挑战的方案

0. 引言 随着互联网技术的发展&#xff0c;网页内容呈现方式越来越复杂&#xff0c;大量网站使用JavaScript动态渲染内容&#xff0c;这给传统的网络爬虫带来了巨大挑战。在2025年的网络爬虫领域&#xff0c;Scrapy和Playwright的结合为我们提供了一个强大的解决方案&#xff…...

可靠消息投递demo

以下是一个基于 Spring Boot RocketMQ 的完整分布式事务实战 Demo&#xff0c;包含事务消息、本地事务、自动重试、死信队列&#xff08;DLQ&#xff09; 等核心机制。代码已充分注释&#xff0c;可直接运行。 一、项目结构 src/main/java ├── com.example.rocketmq │ …...

阻止 Mac 在运行任务时进入休眠状态

掌握Caffeinate命令&#xff1a;让您的 Mac 保持清醒以完成关键任务 开发人员经常发现自己在 Mac 上运行持续时间较长的进程。无论是大量文件上传、广泛的数据分析脚本&#xff0c;还是复杂的构建过程&#xff0c;我们最不希望的就是我们的机器在任务中途进入睡眠状态。输入 c…...

Copilot提示词库用法:调整自己想要的,记住常用的,分享该共用的

不论你是 Microsoft 365 Copilot 的新用户还是熟练运用的老鸟&#xff0c;不论你是使用copilot chat&#xff0c;还是在office365中使用copilot&#xff0c;copilot提示词库都将帮助你充分使用copilot这一划时代的产品。它不仅可以帮助你记住日常工作中常用的prompt提示词&…...

Python实战(3)-数据库操作

前面说过&#xff0c;可用的SQL数据库引擎有很多&#xff0c;它们都有相应的Python模块。这些数据库引擎大都作为服务器程序运行&#xff0c;连安装都需要有管理员权限。为降低Python DB API的使用门槛&#xff0c;我选择了一个名为SQLite的小型数据库引擎。它不需要作为独立的…...

LeetCode 160 Intersection Of Two Linked Lists 相交链表 Java

题目&#xff1a;找到两个相交列表的起始点&#xff0c;如图c1开始为A和B两个链表的相交点 举例1&#xff1a;8为两个链表的相交点。 注意&#xff1a;相交不止是数值上的相同。 举例2&#xff1a;2为相交点 举例3&#xff1a;没有相交点 解题思路&#xff1a; 相交证明最后一…...