1.3.2背包模型(二)

news2025/1/20 17:06:32

1.二维费用的背包问题

N N N件物品和一个容量是 V V V的背包,背包能承受的最大重量是 M M M

每件物品只能用一次。体积是 v i v_{i} vi,重量是 m i m_{i} mi,价值是 w i w_{i} wi

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

输入格式

第一行三个整数, N , V , M , N,V,M, N,V,M用空格隔开,分别表示物品件数、背包容积和背包可承受的最大重量。

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

输出格式

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

数据范围
0 < N ≤ 1000 0<N≤1000 0<N1000
0 < V , M ≤ 100 0<V,M≤100 0<V,M100
0 < v i , m i ≤ 100 0<v_{i},m_{i}≤100 0<vi,mi100
0 < w i ≤ 1000 0<w_{i}≤1000 0<wi1000

输入样例

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

输出样例:

8

1.1题解

与01背包、完全背包、多重背包有很大相似点,只是在考虑状态计算有所差异而已。
在这里插入图片描述

1.2代码实现

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 110;

//n件物品,总体积为V,总重量为W
int n,V,M;
//优化为两维
int f[N][N];

int main()
{
    cin >> n >> V >> M;
    
    for(int i = 0; i < n;i++)
    {
        //体积,重量和价值
        int v,m,w;
        cin >> v >> m >> w;
        for(int j = V;j >= v;j--)
            for(int k = M;k >= m;k--)
                f[j][k] = max(f[j][k],f[j - v][k - m] + w);
    }
    
    
    cout<<f[V][M]<<endl;
    
    return 0;
}

2.潜水员

潜水员为了潜水要使用特殊的装备。

他有一个带 2 2 2种气体的气缸:一个为氧气,一个为氮气。

让潜水员下潜的深度需要各种数量的氧和氮。

潜水员有一定数量的气缸。

每个气缸都有重量和气体容量。

潜水员为了完成他的工作需要特定数量的氧和氮。

他完成工作所需气缸的总重的最低限度的是多少?

例如:潜水员有 5 5 5个气缸。每行三个数字为:氧,氮的(升)量和气缸的重量:

3 36 120

10 25 129

5 50 250

1 45 130

4 20 119

如果潜水员需要 5 5 5升的氧和 60 60 60升的氮则总重最小为 249 249 249 1 1 1 2 2 2或者 4 4 4 5 5 5号气缸)。

你的任务就是计算潜水员为了完成他的工作需要的气缸的重量的最低值。

输入格式
第一行有 2 2 2个整数 m , n m,n mn。它们表示氧,氮各自需要的量。

第二行为整数 k k k表示气缸的个数。

此后的 k k k行,每行包括 a i , b i , c i , 3 a_{i},b_{i},c_{i},3 aibici3个整数。这些各自是:第 i i i个气缸里的氧和氮的容量及气缸重量。

输出格式
仅一行包含一个整数,为潜水员完成工作所需的气缸的重量总和的最低值。

数据范围

1 ≤ m ≤ 21 , 1≤m≤21, 1m21,
1 ≤ n ≤ 79 , 1≤n≤79, 1n79,
1 ≤ k ≤ 1000 , 1≤k≤1000, 1k1000,
1 ≤ a i ≤ 21 , 1≤a_{i}≤21, 1ai21,
1 ≤ b i ≤ 79 , 1≤b_{i}≤79, 1bi79,
1 ≤ c i ≤ 800 1≤c_{i}≤800 1ci800

输入样例:

5 60
5
3 36 120
10 25 129
5 50 250
1 45 130
4 20 119

输出样例:

249

2.1题解

在这里插入图片描述
在这里插入图片描述
算法分析

  • 状态表示f[i,j,k]:所有从前i个物品中选,且氧气含量至少是j,氮气含量至少是k的所有选法的气缸重量总和的最小值
  • 状态计算:
    • 所有不包含物品i的所有选法:f[i - 1,j,k]
    • 所有包含物品i的所有选法:f[i - 1,j - v1,k - v2]

注意:即使所需要的氧气或者氮气所需的是数量是负数,但其所需数量与0是等价的,因此可以通过所需数量为0来转移

扩展
可能很多人会有这样的疑问,二维费用的背包问题的状态转移方程代码如下

for(int j =  V;j >= v;j --)
    for(int k = M;k >= m;k --)
        f[j][k] = max(f[j][k], f[j - v][k - m] + w);

而本题的状态转移方程代码如下

for(int j = V;j >= 0;j --)
    for(int k = M;k >= 0;k --)
        f[j][k] = min(f[j][k], f[max(0, j - v)][max(0, k - m)] + w);

为什么上面的代码 j只需要遍历到vk只能遍历到m。而下面的代码 j还需要遍历到0k还需要遍历到0 ?同时为什么氧气或者氮气所需的是数量是负数时,可以与数量0的状态等价?

解答:对比两题的思路,二维费用的背包问题,求的是不能超过体积V,重量M的情况下,能拿到价值的最大值。而本题是至少需要体积V,重量M的情况下,能拿到价值的最小值。就拿体积来说,至少需要多少体积,也就是说有体积比需要的体积大的物品还是能用得到,例如f[3][5],至少需要3个体积,5个重量,求能拿到价值的最小值,现在只有一个物品,体积是4,重量是4,价值w,它说至少需要3个体积,那么体积是4还是可以用到,只是多了1个体积没用占着而已,不影响其价值。因此若用了这个物品,则变成了求f[0][1] + w,表示体积已经不再需求了,只需要0个体积即可

求最大值最小值初始化总结
二维情况

1、体积至多jf[i,k] = 00 <= i <= n, 0 <= k <= m(只会求价值的最大值)
2、体积恰好j
当求价值的最小值:f[0][0] = 0, 其余是INF
当求价值的最大值:f[0][0] = 0, 其余是-INF
3、体积至少jf[0][0] = 0,其余是INF(只会求价值的最小值)

一维情况
1、体积至多jf[i] = 0, 0 <= i <= m(只会求价值的最大值)
2、体积恰好j
当求价值的最小值:f[0] = 0, 其余是INF
当求价值的最大值:f[0] = 0, 其余是-INF
3、体积至少jf[0] = 0,其余是INF(只会求价值的最小值)

2.2代码实现

#include <cstring>
#include <iostream>

using namespace std;

const int N = 22, M = 80;

int n, m, K;
int f[N][M];

int main()
{
    cin >> n >> m >> K;
    //初始化正无穷的目的是我们在更新的时候不使用这个值
    memset(f, 0x3f, sizeof f);
    f[0][0] = 0;

    while (K -- )
    {
        int v1, v2, w;
        cin >> v1 >> v2 >> w;
        for (int i = n; i >= 0; i -- )
            for (int j = m; j >= 0; j -- )
                f[i][j] = min(f[i][j], f[max(0, i - v1)][max(0, j - v2)] + w);
    }


    cout << f[n][m] << endl;

    return 0;
}


3.数字组合

给定 N N N 个正整数 A 1 , A 2 , … , A N A_{1},A_{2},…,A_{N} A1,A2,,AN,从中选出若干个数,使它们的和为 M M M,求有多少种选择方案。

输入格式
第一行包含两个整数 N N N M M M

第二行包含 N N N个整数,表示 A 1 , A 2 , … , A N A_{1},A_{2},…,A_{N} A1,A2,,AN

输出格式
包含一个整数,表示可选方案数。

数据范围

1 ≤ N ≤ 100 , 1≤N≤100, 1N100,
1 ≤ M ≤ 10000 , 1≤M≤10000, 1M10000,
1 ≤ A i ≤ 1000 , 1≤Ai≤1000, 1Ai1000,

答案保证在 int 范围内。

输入样例:

4 4
1 1 2 2

输出样例:

3

3.1题解

在这里插入图片描述

3.2代码实现

#include<iostream>
#include<algorithm>

using namespace std;
const int N = 10010;
int n,m;
int f[N];

int main()
{
    cin >> n >> m;
    //第一个初始化为1,其余都为0
    f[0] = 1;
    for(int i = 0;i < n;i++)
    {
        int v;
        cin >> v;
        for(int j = m;j >= v;j--)
            f[j] += f[j - v];
    }
       
    cout << f[m] << endl;
    return 0;
    
}

4.庆功会

为了庆贺班级在校运动会上取得全校第一名成绩,班主任决定开一场庆功会,为此拨款购买奖品犒劳运动员。

期望拨款金额能购买最大价值的奖品,可以补充他们的精力和体力。

输入格式
第一行二个数 n n n m m m,其中 n n n代表希望购买的奖品的种数, m m m表示拨款金额。

接下来 n n n行,每行 3 3 3个数, v v v w w w s s s,分别表示第 I I I种奖品的价格、价值(价格与价值是不同的概念)和能购买的最大数量(买 0 0 0件到 s s s件均可)。

输出格式
一行:一个数,表示此次购买能获得的最大的价值(注意!不是价格)。

数据范围
n ≤ 500 , m ≤ 6000 , n≤500,m≤6000, n500,m6000,
v ≤ 100 , w ≤ 1000 , s ≤ 10 v≤100,w≤1000,s≤10 v100,w1000,s10

输入样例:

5 1000
80 20 4
40 50 9
30 50 7
40 30 6
20 20 1

输出样例:

1040

4.1题解

本题为一个朴素版多重背包问题

初始状态:f[0][0]
目标状态:f[n][m]

在这里插入图片描述

4.2代码实现

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 6010;

int n,m;
int f[N];

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

5.买书

小明手里有n元钱全部用来买书,书的价格为 10 10 10元, 20 20 20元, 50 50 50元, 100 100 100元。

问小明有多少种买书方案?(每种书可购买多本)

输入格式
一个整数 n n n,代表总共钱数。

输出格式
一个整数,代表选择方案种数。

数据范围
0 ≤ n ≤ 1000 0≤n≤1000 0n1000

输入样例1:

20

输出样例1:

2

输入样例2:

15

输出样例2:

0

输入样例3:

0

输出样例3:

1

5.1题解

在这里插入图片描述

5.2代码实现

#include<iostream>

using namespace std;

const int N = 1010;

int v[4] = {10,20,50,100};
int f[N];

int main()
{
    int m;
    cin >> m;
    
    f[0] = 1;
    for(int i = 0;i < 4;i++)
        for(int j = 0;j <= m;j++)
            if(j >= v[i])
                f[j] += f[j - v[i]];
    
    cout << f[m] <<endl;
    
    return 0;
}

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

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

相关文章

想要搞懂接口测试和功能测试有什么区别,那就必须知道他们的基本原理

本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什么要做&#xff1f; 第二部分&#xf…

图形化管理工具ossbrowser

文章目录 一、OSS介绍二、通过工具管理OSS三、安装四、使用-通过AK五、免责声明摘抄 一、OSS介绍 云对象存储OSS&#xff08;Object Storage Service&#xff09;是一款海量、安全、低成本、高可靠的云存储服务&#xff0c;可提供99.9999999999%&#xff08;12个9&#xff09;…

WebGL:基于web的交互式2D/3D图形引擎

推荐&#xff1a;使用 NSDT编辑器 快速搭建3D应用场景 在本指南中&#xff0c;我们旨在回答与WebGL技术相关的大多数问题。首先&#xff0c;让我们从WebGL定义开始。 什么是WebGL&#xff1f; WebGL&#xff08;Web图形库&#xff09;是一个JavaScript应用程序编程接口&#x…

Python学习 -- 异常捕获技巧

在编写Python代码时&#xff0c;异常处理是确保程序稳定性的关键。Python提供了灵活的异常捕获机制&#xff0c;包括try...except语句、try...except...else语句和try...except...finally语句。本文将详细介绍这些异常处理技巧&#xff0c;并为每种情况提供代码案例。 一、try…

数字孪生:先进技术与未来发展的洞察

数字孪生&#xff1a;先进技术与未来发展的洞察 随着数字技术的迅猛发展&#xff0c;数字孪生作为新兴的概念和技术应运而生。数字孪生能够将现实世界与虚拟世界紧密连接&#xff0c;通过实时监测、数据分析和模拟仿真&#xff0c;为企业提供优化运营、提高效率和质量的解决方案…

透明度高达70%:OLED透明屏原屏在展示器材上的创新应用

OLED透明屏原屏作为一种领先的显示技术&#xff0c;正在引起越来越多企业和消费者的关注。 根据最新的行业数据和报告&#xff0c;OLED透明屏原屏在各个应用领域都展现出卓越的性能和创新的设计特点。 本文将通过深入探讨OLED透明屏原屏的优势和特点、应用领域、技术发展以及…

python的异步编程async

一、介绍 在Python 3.5中引入了async和await关键字&#xff0c;用于异步编程。async关键字用于定义一个协程&#xff08;coroutine&#xff09;&#xff0c;而await关键字则用于等待一个协程完成。 注&#xff1a;协程&#xff08;coroutine&#xff09;是是一种轻量级的线程…

易趋亮相PMOPM大会,分享项目型业务数字化方法与实践

8月26-27日&#xff0c;第二届中国PMO&PM大会在北京、上海、深圳三地同步举行并圆满落幕。大会以“价值交付•重塑未来”为主题&#xff0c;设置了包括“项目管理方法论”、“PMO管理运营”、“组织项目治理”、“创新变革管理”、“项目管理人才”、“前沿趋势和技术”等六…

leetcode 2483. Minimum Penalty for a Shop(商店的最少代价)

字符串customers只包含’Y’和’N’两种字母, 表示 i 时刻商店是否有客人来。 如果商店在 i 时刻处于开门状态&#xff0c;Y’的代价是0&#xff0c;N’的代价是1.&#xff08;开门了却没有客人就算损失&#xff09;。 反之&#xff0c;在 i 时刻处于关门状态&#xff0c;N’的…

【Linux】centos8安装cmake3.27.4

第一步&#xff0c;去官网下安装包&#xff0c;一定不要下错了 下好了之后&#xff0c;用ftp软件传到云服务器或者虚拟机上&#xff0c;我用的是centos8系统&#xff0c;安装之前先准备好这些依赖项 yum install -y gcc gcc-c make automake yum install -y openssl openssl-…

Docker原理详细剖析-Namespace

一、简介 docker容器技术从2013年开始火了以后&#xff0c;2014年左右当时有幸在学校能和学院教授一起做些项目以及学习。其中docker技术在当时来说还算是比较新的技术&#xff0c;国内关于这块的资料以及使用也才刚刚开始&#xff0c;讨论docker技术&#xff0c;算是相对时髦的…

华为OD机试 - 生日礼物 - 二分查找(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 一、题目描述 小牛的孩子生日快要到了&#xff0c;他打算给孩子买蛋糕和小礼物&#xff0c;蛋糕和小礼物…

100天精通Golang(基础入门篇)——第19天:深入剖析Go语言中方法(Method)的妙用与实践

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to Golang Language.✨✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1…

Python2022年09月Python二级 -- 编程题解析

第一题: 某航空公司对于托运行李有尺寸要求&#xff0c;必须满足以下条件:每件托运行李的长、宽、高三边之和须大于或等于60厘米&#xff0c;且小于或等于203厘米。(注意只是三边&#xff0c;不考虑立方体的整个周长&#xff0c;相当于只求长宽高三个数字的和&#xff0c;如&am…

Mysql的page,索引,Explain Type等基本常识

Mysql的基本问题 Mysql 为什么建议使用自增id&#xff1f; 因为id&#xff08;主键&#xff09;是自增的话&#xff0c;那么在有序的保存用户数据到页中的时候&#xff0c;可以天然的保存&#xff0c;并且是在聚集索引&#xff08;id&#xff09;中的叶子节点可以很好的减少插…

STM32H750+LAN8720无操作系统移植lwip

前言 本文提供移植好的工程&#xff0c;见本文绑定资源 环境 STM32CubeMX&#xff1a; V6.8.1 STM32H7 HAL Pack&#xff1a; V1.11.1 硬件连接 STM32H750 GPIO定义如下&#xff1a; LAN8720 GPIO定义如下&#xff1a; 连接方式如下&#xff1a; LAN8720       <—…

翻斗式雨量计入选【2023年济南市重点工业新产品】名单

近日&#xff0c;济南市工业和信息化局发布了【2023年济南市重点工业新产品】名单&#xff0c;山东仁科测控技术有限公司“翻斗式雨量计”成功入选。 为深入实施工业强市战略&#xff0c;切实加强创新示范推广与应用&#xff0c;鼓励企业研发新技术、新产品、新工艺&#xff0…

Android Native Code开发学习(三)对java中的对象变量进行操作

Android Native Code开发学习&#xff08;三&#xff09; 本教程为native code学习笔记&#xff0c;希望能够帮到有需要的人 我的电脑系统为ubuntu 22.04&#xff0c;当然windows也是可以的&#xff0c;区别不大 对java中的对象变量进行操作 首先我们新建一个java的类 pub…

全画面塑料激光透光率测试仪

随着光学塑料成型技术的不断发展&#xff0c;光学塑料透镜在各类光学系统中得到了广泛的应用。光学塑料具有便于大批量生产&#xff0c;设计灵活性高&#xff0c;重量轻和耐冲击等特点。最近几年来&#xff0c;国内外有许多专家学者对热塑性半结晶塑料激光焊接工艺上的应用进行…

Java入门第四节

Java入门第四节 一.继承 问题&#xff1a; 隔壁的王阿姨养了一只猫和一只仓鼠&#xff0c;也想使用这个app&#xff0c;应该这么办 解决&#xff1a; 1.找出所有动物的共性(如.有名字&#xff0c;品种&#xff0c;年龄&#xff0c;吃饭&#xff0c;跑等等)&#xff0c;创建…