首页 > 其他分享 >笔试题11 -- 装箱问题(01背包)

笔试题11 -- 装箱问题(01背包)

时间:2024-11-08 16:14:53浏览次数:6  
标签:11 箱子 01 -- 体积 vec 物品 递推 dp

装箱问题(01背包)

文章目录

题目链接:NOIP2001装箱问题

一、原题复现

题目描述

有一个箱子容量为V(正整数,0 ≤ V ≤ 20000),同时有n个物品(0<n ≤ 30),每个物品有一个体积(正整数)。
要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

输入描述:

  • 1个整数,表示箱子容量
  • 1个整数,表示有n个物品
  • 接下来n行,分别表示这n个物品的各自体积

输出描述:

1个整数,表示箱子剩余空间。

输入

24
6
8
3
12
7
9
7

输出

0

二、思路剖析

  1. 首先观察题中希望得到剩余空间最小时剩余的空间值,要达到该要求,需要我们塞入体积总和尽可能多的物体。由于每个物体的体积都是正数,不妨我们将最终推测的目标转换为从众多物品中选取,在总体积不超过V的情况下,使得箱子内的物品总体积尽可能大。最终返回的结果即:“V - 最大总体积”。

  2. 对于每个物品,他们都有各自对应的体积大小,同时对于达成最终目标而言,都有选择与不被选择两种情况,这两种情况可以分别表示为 ‘0’, ‘1’ ,所以该题应该将 01 背包问题纳入考虑范围。

  3. 因为有总体积不超过V的限制,所以我们dp数组递推的过程有一个字段是**“峰值容量”**,它的递推范围为 [0, V]。当然,峰值容量为0时,不能装任何物品,那么该字段为0对应的dp表空位可以直接初始化为0。

  4. 同样地,因为有n个物品,对他们进行标号,也就有了另外一个字段为**“物品序号”**,递推范围为 [1, n],直接表示为第i个物品。

  5. 通过上面 (3)、(4) 的分析,最终的 dp 表在两字段对应都需要多开一个位置,便于初始化完成后,对剩余位置的循环递推赋值。不妨设定 i 为前 i 件物品理由:由于判断第 i 物品时,峰值容量是否足够容纳该物品,而判断总体积时前面的物品也已经装在箱子中,j 为箱子内可容纳的峰值容量。 dp[i] [j] 表示前 i 件物品,在总体积不超过 j 的情况下,箱子内的最大体积。

  6. 截止目前我们已经确定了dp表,以及 dp[i] [j] 的含义和 i ,j 的递推范围。那怎么通过其他表格内的信息推出 dp[i] [j] 的值呢?假定存储物品的数组声明为"vec",我们知道对于第 i 个物品存在 选、不选 两种情况:

    • 不选:那么前 i 位置相对于前 i - 1 位置,vec[i]的值就没有叠加,故 dp[i] [j] = dp[i - 1] [j]
    • 选:对于选而言,有个重要的前提,即为当前峰值容量(j) 减去当前物品的体积(vec[i]) 是否大于0。如果大于等于0,说明如果箱内为空可以容纳下该物体,那么此时的最大体积为前 i - 1 个物体,箱子峰值容量为 j - vec[i] 处对应的值加上 vec[i],即 dp[i - 1] [j - vec[i]] + vec[i]。另外一种递推渠道 dp[i - 1] [j],最终 dp[i] [j] 位置的值取两者的最大值即可;如果小于0,递推来源就只能是 dp[i - 1] [j],即 dp[i] [j] = dp[i - 1] [j]

在这里插入图片描述

  1. 填表顺序也通过上面分析变得很清晰了,最终状态是什么呢? 回到开始,我们将问题转换为利用dp表求在总体积不超过V的情况下,使得箱子内的物品总体积尽可能大。所以,最终状态对应的值为 dp[n] [v],注意我们循环递推填表下标从 1 开始。最后得到的结果即 v - dp[n] [v]

三、示例代码

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    int v = 0, n = 0;
    cin >> v >> n;
    vector<int> vec(n + 1, 0);
    for(int i = 1; i <= n; i++)
    {
        cin >> vec[i];
    }
    
    // dp[i][j]: 表示前i个物品,容量不超过j的情况下,箱子的峰值容量
    vector<vector<int>> dp(n + 1, vector<int>(v + 1));
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= v; j++)
        {
            dp[i][j] = (j < vec[i])? 
                       (dp[i - 1][j]): 
                       (max(dp[i - 1][j], 
                           dp[i - 1][j - vec[i]] + vec[i]));
        }
    }
    
    auto result = v - dp[n][v];
    cout << result << endl;
    
    return 0;
}

在这里插入图片描述

标签:11,箱子,01,--,体积,vec,物品,递推,dp
From: https://blog.csdn.net/2301_78694061/article/details/143629631

相关文章

  • API接口实战:获取商品详情信息的奇幻之旅
    在编程的世界里,API接口就像是通往宝藏的神秘地图。今天,我们将踏上一段奇幻之旅,目标是获取商品详情信息。准备好了吗?让我们的代码小船扬帆起航!第一章:了解地图——API接口的基本概念想象一下,你是一位探险家,面前摆着一张古老的地图,上面标记着“商品详情”的神秘宝藏。这张地图,就......
  • TMC4671使用笔记
    1、单向DC电机开环测试voidTMC4671SinglePhaseDC_Test(){//电机类型和PWM配置//TMC4671_MOTOR_TYPE_N_POLE_PAIRS寄存器用于设置电机类型和极对数。//高16位(0x0001):电机类型。0:无电机1:单相直流电机2:两相步进电机3:三相无刷电机//低16位......
  • python
    python之基本介绍(1)什么是python?python是一门编程语言python是一门面向对象,解释型的动态类型的编程语言(2)什么是面向对象?python中一切皆为对象,对事物的描述和方法系统的定义为一个类,在这个类中的具体的实例,我们就说对象;(3)什么解释型?python程序执行时无需先进行编译成二进......
  • [赛记] 多校A层冲刺NOIP2024模拟赛19
    图书管理85pts2s1e10助我85pts;考虑正解,仍然是算贡献;这个题有一个很通用的套路:将大于某数的数看成$1$,小于这个数的数看成$0$;那么我们枚举$a_i$,运用上面的套路将$i$左边的前缀和算出来并开个桶记录一下端点编号之和,然后在枚举$i$右边的同时找到现在的前缀和......
  • gitignore修改后怎么生效
    目录从Git跟踪中移除已经被忽略的文件添加.gitignore文件到仓库提交更改推送到远程仓库修改.gitignore文件后,要使更改生效,你需要重新提交该文件到Git仓库。如果你已经添加了新的规则到.gitignore,但是Git仍然跟踪某些应该被忽略的文件,可能是因为这些文件已经被提交到了仓库中。......
  • Azure VM (44) Azure 虚拟机反向DNS记录
    《WindowsAzurePlatform系列文章目录》 AzureVM设置反向DNS记录1.首先,先创建1台AzureVM,部署在AzureGermanyWestCentral。给这台虚拟机挂载1个公网IP地址2.在自己的DNS域名解析商,做CNAME解析,比如:lei.cyyyt.net做CNAME解析到azure的公网IP域名:leire......
  • 通过Guava实现ip限流访问
    一分钟内某个ip请求制定接口超过10次,则禁止该ip10分钟内不能访问,通过Guava实现一个拦截器,拦截指定接口来处理 mportcom.google.common.cache.Cache;importcom.google.common.cache.CacheBuilder;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.ato......
  • 树上背包
    树上的背包问题,也就是背包问题与树形DP的结合。例题:P2014[CTSC1997]选课有\(n\)门课程,第\(i\)门课程的学分为\(a_i\),每门课程有零门或一门先修课,有先修课的课程需要先学完其先修课,才能学习该课程。一位学生要学习\(m\)门课程,求其能获得的最多学分数。数据范围:\(n,m......
  • ES 布尔查询中 minimum_should_match 参数使用避坑
    简介: ES布尔查询中minimum_should_match参数使用避坑在Elasticsearch(ES)中,布尔查询(BooleanQuery)是一种查询类型,它允许你组合多个查询子句以控制搜索结果的匹配逻辑。minimum_should_match是布尔查询中一个重要的参数,用于指定至少应该匹配的子句数量。 mini......
  • NOIP2024 前集训:多校A层冲刺NOIP2024模拟赛19
    前言这次不是之前学长吃完吐出来的shi,这次是新拉的热乎的烫嘴的shi。T1、2、3、4大样例全部错一遍,T1题面和时限再错一遍哈哈哈。T4假做法有60哈哈哈,大样例跑出来半个对的都没有能得60哈哈哈。accodersT1前半小时没数据做得快的全部都死哈哈(还好我第一份被卡常了后......