1.3.1背包模型(一)

news2024/11/25 4:44:07

在这里插入图片描述

01背包
划分依据:依靠“最后一步”来划分
在这里插入图片描述
完全背包

在这里插入图片描述

在这里插入图片描述

多重背包
在这里插入图片描述

完全背包:求所有前缀的最大值
多重背包:求滑动窗口内的最大值

1.多重背包问题 III

N N N种物品和一个容量是 V V V的背包。

i i i种物品最多有 s i s_{i} si件,每件体积是 v i v_{i} vi,价值是 w i w_{i} wi

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

输入格式
第一行两个整数, N , V ( 0 < N ≤ 1000 , 0 < V ≤ 20000 ) N,V (0<N≤1000, 0<V≤20000) NV(0<N1000,0<V20000),用空格隔开,分别表示物品种数和背包容积。

接下来有 N N N行,每行三个整数 v i v_{i} vi, w i w_{i} wi, s i s_{i} si用空格隔开,分别表示第 i种物品的体积、价值和数量。

输出格式
输出一个整数,表示最大价值。

数据范围
0 < N ≤ 1000 0<N≤1000 0<N1000
0 < V ≤ 20000 0<V≤20000 0<V20000
0 < v i , w i , s i ≤ 20000 0<v_{i},w_{i},s_{i}≤20000 0<vi,wi,si20000

提示
本题考查多重背包的单调队列优化方法。

输入样例

4 5
1 2 3
2 4 1
3 4 3
4 5 2

输出样例:

10
1.1题解

难度警告!本题为楼教主男人八题之一,量力而行!
题目大意:
  本题为多重背包问题
解题方法:
我们先分析一下式子吧。
在这里插入图片描述
好了,我来解释一下这些式子
r r r:就是 j j j 一直减去 v v v最后剩下的余数。

然后我们会发现这回不能用之前的式子推了,因为 f [ i ] [ j − v ] f[i][j−v] f[i][jv]后面多出了一项。我们知道最后一项的值,但是却不能因此推出前面这几项的值。
数学老师经常跟我们说:遇事不决就画图。那我就画一个试一试。
在这里插入图片描述
我只是示意一下,这个图底下标的就是体积
我们会发现,每个 f f f数组里的数,转移的都是一个长度为 k + 1 k+1 k+1的区间!
在图中就是这样体现的:

f [ i ] [ j ] f[i][j] f[i][j]不就是从 f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − v ] + w , f [ i − 1 ] [ j − 2 v ] + 2 w . . . . . . f [ i − 1 ] [ j − s v ] + s w f[i−1][j] ,f[i−1][j−v]+w,f[i−1][j−2v]+2w......f[i−1][j−sv]+sw f[i1][j]f[i1][jv]+wf[i1][j2v]+2w......f[i1][jsv]+sw
转移过来的,就是一个长度为 s+1的窗口!

好了这道题你就已经做了一半了,喝口水休息一下吧~


接下来继续往下看。
我们会发现,一开始的式子,对应到这个数轴上,就是越往左边加的 w w w越大,所以我们需要体现出越往左加的 w w w越多的这个优势,所以式子变成了这样:

在这里插入图片描述
也就是每个对应上减去一些 w w w

在这里插入图片描述
问题环节:
我Q:为什么要这么做呢?你是不是闲的蛋疼???
我A:具体就是 当前下标 和该 最大值的下标 之间差了 x x x v v v,那么就要加上 x x x w w w重点就是比较的时候是比较相对大小而不是绝对大小!!!讲细一点就是说你无法确定单调队列里的数到底加上了几个 w w w,就无法比较了。
我Q: 懂了懂了nbnb点赞点赞。

1.2代码实现

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 20010;
int n, m;
int f[N], g[N], q[N];
//拷贝数组,因为这里不能使用一维优化,因为如果倒叙枚举,你就不能用滑动窗口了。

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i ++ ) {
        int v, w, s;
        cin >> v >> w >> s;
        memcpy(g, f, sizeof f);
        for (int j = 0; j < v; j ++ ) {
            int hh = 0, tt = -1;
            for (int k = j; k <= m; k += v) {
                if (hh <= tt && q[hh] < k - s * v) hh ++ ; //剔除超出长度元素
                if (hh <= tt) f[k] = max(f[k], g[q[hh]] + (k - q[hh]) / v * w); //更新当前答案
                while (hh <= tt && g[q[tt]] - (q[tt] - j) / v * w <= g[k] - (k - j) / v * w) tt -- ;
                //维持单调性
                //这里也可以这样写,更易理解
                //while (hh <= tt && g[q[tt]] <= g[k] - (k - q[tt]) / v * w) tt -- ;
                q[ ++ tt] = k;
            } 
        }
    }
    cout << f[m] << endl;
    return 0;
}

2.采药

辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。

为此,他想拜附近最有威望的医师为师。

医师为了判断他的资质,给他出了一个难题。

医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

输入格式
输入文件的第一行有两个整数 T T T M M M,用一个空格隔开, T T T代表总共能够用来采药的时间, M M M代表山洞里的草药的数目。

接下来的 M M M行每行包括两个在 1 1 1 100 100 100之间(包括 1 1 1 100 100 100)的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出格式
输出文件包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

数据范围
1 ≤ T ≤ 1000 1≤T≤1000 1T1000,
1 ≤ M ≤ 100 1≤M≤100 1M100
输入样例:

70 3
71 100
69 1
1 2

输出样例:

3

2.1题解

参考01背包

2.2代码

#include<iostream>

using namespace std;

const int N = 1010;

int n,m;
int f[N];

int main()
{
    cin>>m>>n;
    for(int i = 0; i < n;i++)
    {
        int v,w;
        cin>>v>>w;
        for(int j = m;j >= v;j--)   f[j] = max(f[j],f[j - v] + w);
    }
    
    cout<<f[m]<<endl;
    
    return 0;
}

3.装箱问题

有一个箱子容量为 V V V,同时有 n n n 个物品,每个物品有一个体积(正整数)。

要求 n n n 个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

输入格式
第一行是一个整数 V V V,表示箱子容量。

第二行是一个整数 n n n,表示物品数。

接下来 n n n 行,每行一个正整数(不超过 10000 10000 10000),分别表示这 n n n 个物品的各自体积。

输出格式
一个整数,表示箱子剩余空间。

数据范围
0 < V ≤ 20000 0<V≤20000 0<V20000,
0 < n ≤ 30 0<n≤30 0<n30
输入样例:

24
6
8
3
12
7
9
7

输出样例:

0
3.1题解

此题为01背包变形题目,注意,此题需要将体积看为价值即可。

3.2代码实现

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 20010;

int m,n;
int f[N];
int main()
{
    cin>>m>>n;
    for(int i = 0;i < n;i++)
    {
        int v;
        cin>>v;
        //m表示容量
        for(int j = m;j >= v;j--) f[j] = max(f[j],f[j - v] + v);

    }
    //注意:剩余空间
    cout<<m - f[m]<<endl;
    
    return 0;
}

4宠物小精灵之收服

宠物小精灵是一部讲述小智和他的搭档皮卡丘一起冒险的故事。

一天,小智和皮卡丘来到了小精灵狩猎场,里面有很多珍贵的野生宠物小精灵。

小智也想收服其中的一些小精灵。

然而,野生的小精灵并不那么容易被收服。

对于每一个野生小精灵而言,小智可能需要使用很多个精灵球才能收服它,而在收服过程中,野生小精灵也会对皮卡丘造成一定的伤害(从而减少皮卡丘的体力)。

当皮卡丘的体力小于等于0时,小智就必须结束狩猎(因为他需要给皮卡丘疗伤),而使得皮卡丘体力小于等于0的野生小精灵也不会被小智收服。

当小智的精灵球用完时,狩猎也宣告结束。

我们假设小智遇到野生小精灵时有两个选择:收服它,或者离开它。

如果小智选择了收服,那么一定会扔出能够收服该小精灵的精灵球,而皮卡丘也一定会受到相应的伤害;如果选择离开它,那么小智不会损失精灵球,皮卡丘也不会损失体力。

小智的目标有两个:主要目标是收服尽可能多的野生小精灵;如果可以收服的小精灵数量一样,小智希望皮卡丘受到的伤害越小(剩余体力越大),因为他们还要继续冒险。

现在已知小智的精灵球数量和皮卡丘的初始体力,已知每一个小精灵需要的用于收服的精灵球数目和它在被收服过程中会对皮卡丘造成的伤害数目。

请问,小智该如何选择收服哪些小精灵以达到他的目标呢?

输入格式

输入数据的第一行包含三个整数: N , M , K N,M,K NMK,分别代表小智的精灵球数量、皮卡丘初始的体力值、野生小精灵的数量。

之后的K行,每一行代表一个野生小精灵,包括两个整数:收服该小精灵需要的精灵球的数量,以及收服过程中对皮卡丘造成的伤害。

输出格式

输出为一行,包含两个整数: C , R C,R CR,分别表示最多收服 C C C个小精灵,以及收服 C C C个小精灵时皮卡丘的剩余体力值最多为R。

数据范围
0 < N ≤ 1000 0<N≤1000 0<N1000,
0 < M ≤ 500 0<M≤500 0<M500,
0 < K ≤ 100 0<K≤100 0<K100

输入样例1:

10 100 5
7 10
2 40
2 50
1 20
4 20

输出样例1:

3 30

输入样例2:

10 100 5
8 110
12 10
20 10
5 200
1 110

输出样例2:

0 100

4.1题解

二维费用01背包问题
在这里插入图片描述

注意:题目说道:使得皮卡丘体力小于等于0的野生小精灵也不会被小智收服,因此皮卡丘的体力值需在V2 - 1时开始

4.2代码实现

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010, M = 510;

int n, V1, V2;
int f[N][M];

int main()
{
    cin >> V1 >> V2 >> n;
    for (int i = 0; i < n; i ++ )
    {
        int v1, v2;
        cin >> v1 >> v2;
        for (int j = V1; j >= v1; j -- )
            for (int k = V2 - 1; k >= v2; k -- )
                f[j][k] = max(f[j][k], f[j - v1][k - v2] + 1);
    }

    cout << f[V1][V2 - 1] << ' ';
    int k = V2 - 1;//找到当前皮卡丘消耗体力最少的情况
    while (k > 0 && f[V1][k - 1] == f[V1][V2 - 1]) k -- ;
    cout << V2 - k << endl;

    return 0;
}


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

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

相关文章

激活函数总结(二十二):激活函数补充(Soft Exponential、ParametricLinear)

激活函数总结&#xff08;二十二&#xff09;&#xff1a;激活函数补充 1 引言2 激活函数2.1 Soft Exponential激活函数2.2 ParametricLinear激活函数 3. 总结 1 引言 在前面的文章中已经介绍了介绍了一系列激活函数 (Sigmoid、Tanh、ReLU、Leaky ReLU、PReLU、Swish、ELU、SE…

机器人制作开源方案 | 桌面级机械臂--仿真设计

1. Ros概述 ROS是一个适用于机器人编程的框架&#xff0c;这个框架把原本松散的零部件耦合在了一起&#xff0c;为它们提供了通信架构。ROS虽然叫做操作系统&#xff0c;但并非Windows、Mac那样通常意义的操作系统&#xff0c;它只是连接了操作系统和你开发的ROS应用程序&#…

AODV代码实现详解——原理与源码分析(一)

首先来几个标准参考&#xff1a; RFC 3561 RFC 3561 中文翻译 一个博客 挺好的另一个博客 事件&#xff1f; 字段长度&#xff1f; 事件驱动 各种定时器 状态转移图&#xff1f; AODV协议 基本概念 AODV&#xff08;Ad hoc On-Demand Distance Vector&#xff09;是一种基于…

Flutter问题记录 - Unable to find bundled Java version

新版本的Android Studio真的移除了JRE&#xff0c;jre目录找不到&#xff0c;怪不得报错了&#xff0c;不过多了一个jbr目录&#xff0c;找了个以前的Android Studio版本对比 搜了一下jbr&#xff08;JetBrains Runtime&#xff09;&#xff0c;原来IDEA老早就开始用了&#xf…

Redis 7 教程 数据持久化

总体 RDB 介绍 RDB 持久化以指定的时间间隔执行数据集的时间点快照 。 把某一时刻的数据和状态以文件的形式写到磁盘上,即使出现故障宕机,快照文件也不会丢失,数据的可靠性得到保证。快照文件就是RDB(Redis DataBase)文件(dump.rdb) 作用 在指定的时间间隔内将内存中的数…

财务数据分析怎么做?看看奥威BI数据可视化工具的解法

从以往的BI智能数据可视化分析项目来看&#xff0c;要想快刀砍乱麻地做好财务数据分析&#xff0c;为企业运营决策提供更加直观深入的数据支持&#xff0c;那就需要为财务数据分析做好数据导入、建模、报表制作、展示等多方面的准备。奥威BI数据可视化工具为此特意打造了一套标…

C#实战:基于腾讯OCR技术实现企业证书识别和数据提取实践

一、OCR技术介绍 在当今数字化时代&#xff0c;OCR&#xff08;Optical Character Recognition&#xff09;识别技术正发挥着越来越重要的作用。OCR技术通过将图像中的文字转化为可编辑的文本形式&#xff0c;实现了对大量纸质文档的数字化处理和信息提取。常见的有企业资质证…

【uniapp】 实现公共弹窗的封装以及调用

图例&#xff1a;红框区域为 “ 内容区域 ” 一、组件 <!-- 弹窗组件 --> <template> <view class"add_popup" v-if"person.isShowPopup"><view class"popup_cont" :style"{width:props.width&&props.width&…

【VLDB 2023】基于预测的云资源弹性伸缩框架MagicScaler,实现“高QoS,低成本”双丰收

开篇 近日&#xff0c;由阿里云计算平台大数据基础工程技术团队主导&#xff0c;与计算平台MaxCompute团队、华东师范大学数据科学与工程学院、达摩院合作&#xff0c;基于预测的云计算平台资源弹性伸缩框架论文《MagicScaler: Uncertainty-aware, Predictive Autoscaling 》被…

解锁市场进入成功:GTM 策略和即用型示例

在最初的几年里&#xff0c;创办一家初创公司可能会充满挑战。根据美国小企业管理局的数据&#xff0c;大约三分之二的新成立企业存活了两年&#xff0c;几乎一半的企业存活了五年以上。导致创业失败的因素有市场需求缺失、资金短缺、团队不合适、成本问题等。由此&#xff0c;…

Flutter可执行屏幕动画的AnimateView

1.让动画使用起来就像使用widget。 2.可自定义动画。 3.内置平移动画。 演示&#xff1a; 代码: import dart:math; import package:flutter/cupertino.dart;class AnimateView extends StatefulWidget {///子Widgetfinal Widget child;///动画自定义final IAnimate? anim…

什么,一条指令直接黑了数据库!

什么&#xff0c;一条指令直接黑了数据库&#xff01; shigen最近研究了一下一款渗透工具sqlMap。它一款流行的开源工具&#xff0c;用于自动化SQL注入攻击和渗透测试。它专门设计用于检测和利用Web应用程序中的SQL注入漏洞。SQLMap具有丰富的功能集&#xff0c;可自动检测和利…

工厂方法模式的概述和使用

目录 一、工厂方法模式概述1. 定义2. 使用动机 二、工厂方法模式结构1. 模式结构2. 时序图 三、工厂方法模式的使用实例四、工厂方法模式的优缺点五、工厂方法模式在Java中应用 原文链接 一、工厂方法模式概述 1. 定义 工厂方法模式(Factory Method Pattern)又称为工厂模式&…

高通面临难题,Oryon核心存在问题,高通8cx Gen 4芯片将推迟发布

"高通公司面临难题&#xff0c;可能会导致骁龙8cx Gen 4的发布时间推迟"&#xff0c;关于骁龙8cx Gen 4处理器&#xff0c;还有一些其他值得关注的特点和功能。首先&#xff0c;据悉&#xff0c;骁龙8cx Gen 4采用了高通自家研发的Oryon核心架构&#xff0c;这是一项…

春秋云镜 Brute4Road

flag1 fscan扫描发现&#xff0c;6379开放ftp可以匿名登录 这里直接尝试了去打redis但是只有主从复制能成功&#xff08;这里应该是靶场有设置吧&#xff0c;对6379操作过后再次操作就会显示端口拒绝访问直接重置就可以了&#xff09; 之后用脚本一把梭哈即可获得shell #更改…

C++ list模拟实现

list模拟实现代码&#xff1a; namespace djx {template<class T>struct list_node{T _data;list_node<T>* _prev;list_node<T>* _next;list_node(const T& x T()):_data(x),_prev(nullptr),_next(nullptr){}};template<class T,class Ref,class Pt…

好用的网页制作工具就是这6个,快点来看!

对于网页设计师来说&#xff0c;好用的网页设计工具是非常重要的&#xff0c;今天本文收集了6个好用的网页设计工具供设计师自由挑选使用。在这6个好用的网页设计工具的帮助下&#xff0c;设计师将获得更高的工作效率和更精致的网页设计效果&#xff0c;接下来&#xff0c;就一…

Android studio APK切换多个摄像头(Camera2)

1.先设置camera的权限 <uses-permission android:name"android.permission.CAMERA" /> 2.布局 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"and…

vue过渡及动画

文章目录 前言类名使用自己定义动画样式多个元素过渡使用第三方库 前言 对于vue中的过渡与动画&#xff0c;官网上是这样概述的&#xff1a; Vue 在插入、更新或者移除 DOM 时&#xff0c;提供多种不同方式的应用过渡效果。包括以下工具&#xff1a; 在 CSS 过渡和动画中自动…

基于空洞卷积DCNN与长短期时间记忆模型LSTM的dcnn-lstm的回归预测模型

周末的时候有时间鼓捣的一个小实践&#xff0c;主要就是做的多因子回归预测的任务&#xff0c;关于时序数据建模和回归预测建模我的专栏和系列博文里面已经有了非常详细的介绍了&#xff0c;这里就不再多加赘述了&#xff0c;这里主要是一个模型融合的实践&#xff0c;这里的数…