3.8 动态规划 背包问题

一.01背包

46. 携带研究材料(第六期模拟笔试) (kamacoder.com)

代码随想录 (programmercarl.com)

携带研究材料:

时间限制:5.000S  空间限制:128MB

题目描述:

小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。他需要带一些研究材料,但是他的行李箱空间有限。这些研究材料包括实验设备、文献资料和实验样本等等,它们各自占据不同的空间,并且具有不同的价值。 

小明的行李空间为 N,问小明应该如何抉择,才能携带最大价值的研究材料,每种研究材料只能选择一次,并且只有选与不选两种选择,不能进行切割。

输入描述:

第一行包含两个正整数,第一个整数 M 代表研究材料的种类,第二个正整数 N,代表小明的行李空间。

第二行包含 M 个正整数,代表每种研究材料的所占空间。 

第三行包含 M 个正整数,代表每种研究材料的价值。

输出描述:

输出一个整数,代表小明能够携带的研究材料的最大价值。

输入示例:

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

 1.dp状态描述

dp[i][j]表示前i个物品中行李空间为j时能带的最大价值   

space[i]表示i物品所需空间

value[i]表示i物品的价值

2.递推公式

先遍历物品再遍历背包空间时
新来一个物品i时面对两种情况 带或不带,带的前提是当前空间>新物品空间I
if(j>=space[i]) dp[i][j]=max(dp[i-1][j-space[i]]+value[i],dp[i-1][j]);
else dp[i][j]=dp[i-1][j]

3. 初始状态

是从一个一个物品开始遍历,初始状态有第一个物品即可(第一行)

    for(int i=0;i<=n;i++)
    {
        if(i>=space[0]) dp[0][i]=value[0];
    }

4.遍历顺序

先遍历物品或背包都可以,但遍历物品更好理解

#include <iostream>
#include <vector>
using namespace std;
int main() {int m = 0, n = 0;cin >> m >> n;vector<int> space,value;int tempM=m;while(tempM--){int tempSpace;cin>>tempSpace;space.push_back(tempSpace);}tempM=m;while(tempM--){int tempValue;cin>>tempValue;value.push_back(tempValue);}// for(auto e : space) cout<<e;// for(auto e : value) cout<<e;//每一个带可能带或不带,前面的选择会影响后面//dp[i][j]表示前i个物品中行李空间为j时能带的最大价值   //新来一个物品i时面对两种情况 带或不带//if(j>=space[i]) dp[i][j]=max(dp[i-1][j-space[i]]+value[i],dp[i-1][j]);//else dp[i][j]=dp[i-1][j]vector<vector<int>> dp(m,vector<int>(n+1,0));// //初始状态第一行即可for(int i=0;i<=n;i++){if(i>=space[0]) dp[0][i]=value[0];}for(int i=1;i<m;i++){for(int j=1;j<=n;j++){if(j>=space[i]) dp[i][j]=max(dp[i-1][j-space[i]]+value[i],dp[i-1][j]);else dp[i][j]=dp[i-1][j];}}cout<<dp[m-1][n];return 0;
}

 二.完全背包

52. 携带研究材料(第七期模拟笔试) (kamacoder.com)

代码随想录 (programmercarl.com)

52. 携带研究材料(第七期模拟笔试)

时间限制:1.000S  空间限制:128MB

题目描述:

小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。他需要带一些研究材料,但是他的行李箱空间有限。这些研究材料包括实验设备、文献资料和实验样本等等,它们各自占据不同的重量,并且具有不同的价值。

小明的行李箱所能承担的总重量为 N,问小明应该如何抉择,才能携带最大价值的研究材料,每种研究材料可以选择无数次,并且可以重复选择。

输入描述:

第一行包含两个整数,N,V,分别表示研究材料的种类和行李空间 

接下来包含 N 行,每行两个整数 wi 和 vi,代表第 i 种研究材料的重量和价值

输出描述:

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

输入示例:

4 5
1 2
2 4
3 4
4 5

输出示例:

10

 1.dp状态描述(与01背包相同)

dp[i][j]表示前i个物品中行李空间为j时能带的最大价值   

space[i]表示i物品所需空间

value[i]表示i物品的价值

2.递推公式

先遍历物品再遍历背包空间时
新来一个物品i时面对两种情况 带或不带,带的前提是当前空间>新物品空间I,带的话可以选择带n个,则带的结果是以dp[i][j-space[i]]+value[i]表示,因为此时只需要空间变小即可,依旧可以选择到第i个物品
if(j>=space[i]) dp[i][j]=max(dp[i][j-space[i]]+value[i],dp[i-1][j]);
else dp[i][j]=dp[i-1][j]

3. 初始状态

是从一个一个物品开始遍历,初始状态有第一个物品即可(第一行),也有01背包略有不同

    for(int i=0;i<=n;i++)
    {
       if(i>=space[0]) dp[0][i]=max(dp[0][i-space[0]]+value[0],value[0]);
    }

#include <iostream>
#include <vector>
using namespace std;
int main() {int m = 0, n = 0;cin >> m >> n;vector<int> space,value;int tempM=m;while(tempM--){int tempSpace,tempValue;cin>>tempSpace>>tempValue;space.push_back(tempSpace);value.push_back(tempValue);}vector<vector<int>> dp(m,vector<int>(n+1,0));// //初始状态第一行即可for(int i=0;i<=n;i++){if(i>=space[0]) dp[0][i]=max(dp[0][i-space[0]]+value[0],value[0]);}for(int i=1;i<m;i++){for(int j=1;j<=n;j++){//与01背包唯一不同点就是选择带之后,依然可以选择继续带,则用dp[i][j-space[i]]+value[i]if(j>=space[i]) dp[i][j]=max(dp[i][j-space[i]]+value[i],dp[i-1][j]);else dp[i][j]=dp[i-1][j];}}cout<<dp[m-1][n];return 0;
}

三.一维数组解题

上述代码中都是按“一行”结束后进行下一行的值计算,且每次计算最多只间隔一行,没有出现间隔多行的情况,在计算第100行时只需要第99行,那么保存的0-98行都是浪费内存。

3.1 01背包

1.状态描述:

dp[j]表示空间为j时能装下的最大重量

2.递推公式:

if(j>=space[i]) dp[j]=max(dp[j-space[i]]+value[i],dp[j]);

3.初始状态
    for(int i=0;i<=n;i++)
    {
        if(i>=space[0]) dp[i]=value[0];
    }

4.遍历顺序

如果是正序:遍历物品i时

假设dp[j]已经装入了物品i,而后的dp[j+n]也可能装入物品i(可能dp[j-space[i]]的值已经变化了 不再是未装入物品i时的值)

举一个例子:物品0的重量weight[0] = 1,价值value[0] = 15

如果正序遍历

dp[1] = dp[1 - weight[0]] + value[0] = 15

dp[2] = dp[2 - weight[0]] + value[0] = 30

此时dp[2]装入了两次物品0

如果是倒序:则不会出现重复装入情况,因为dp[j-space[i]]未变化,未装入物品i

#include <iostream>
#include <vector>
using namespace std;
int main() {int m = 0, n = 0;cin >> m >> n;vector<int> space,value;int tempM=m;while(tempM--){int tempSpace;cin>>tempSpace;space.push_back(tempSpace);}tempM=m;while(tempM--){int tempValue;cin>>tempValue;value.push_back(tempValue);}vector<int> dp(n+1,0);// //初始状态第一行即可for(int i=0;i<=n;i++){if(i>=space[0]) dp[i]=value[0];}for(int i=1;i<m;i++){for(int j=n;j>=space[i];j--){dp[j]=max(dp[j-space[i]]+value[i],dp[j]);}}cout<<dp[n];return 0;
}

 3.2 完全背包

52. 携带研究材料(第七期模拟笔试) (kamacoder.com)

题目与01背包唯一不同点是,物品i可以带入多个

1.将01背包的遍历顺序改为正序

2.修改初始状态 dp[i]=max(dp[i-space[0]]+value[0],value[0]); 

#include <iostream>
#include <vector>
using namespace std;
int main() {int m = 0, n = 0;cin >> m >> n;vector<int> space,value;int tempM=m;while(tempM--){int tempSpace,tempValue;cin>>tempSpace>>tempValue;space.push_back(tempSpace);value.push_back(tempValue);}vector<int> dp(n+1,0);for(int i=space[0];i<=n;i++){dp[i]=max(dp[i-space[0]]+value[0],value[0]);}for(int i=1;i<m;i++){for(int j=space[i];j<=n;j++){dp[j]=max(dp[j-space[i]]+value[i],dp[j]);}}cout<<dp[n];return 0;
}

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

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

相关文章

基于textdistance计算文本相似度

textdistance是Python的第三方库&#xff0c;用于计算文本之间的相似度或距离。它提供了30个算法&#xff0c;简单易用。 安装 pip install textdistance# 使用扩展库&#xff0c;提高性能 pip install "textdistance[extras]"使用 import textdistance# 计算编辑…

提醒一下!今年考研的人不要太老实了!!

今年准备计算机考研的同学&#xff0c;别太老实了&#xff01;别人说什么你就信什么 如果你的工作能力不足以支撑找到一个满意的工作&#xff0c;那我建议再沉淀两年&#xff01; 很多同学其实有点眼高手低&#xff0c;在计算机专业&#xff0c;低于1w的工作看不上&#xff0…

用一个 Python 脚本实现依次运行其他多个带 argparse 命令行参数的 .py 文件

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 问题描述&#xff1a;在 Windows 环境中&#xff0c;您希望通过一个 Python 脚本来实现特定的自动化任务&#xff0c;该任务需要依次运行其他多个带 argparse 命令行参数的 .py 文件。您希望找到一种简…

华为设备小型园区网方案(有线+无线+防火墙)

&#xff08;一&#xff09;配置有线部分 1.配置LSW2 &#xff08;1&#xff09;创建相关vlan [LSW2]vlan batch 10 3000 &#xff08;2&#xff09;配置连接LSW1的Eth-Trunk1&#xff0c;透传VLAN 10 3000 [LSW2]int Eth-Trunk 1 [LSW2-Eth-Trunk1]port link-type trunk [LSW2…

安装nexus + 部署私有maven仓库

安装nexus 部署私有maven仓库 文章目录 安装nexus 部署私有maven仓库1.下载2.解压3.修改配置文件4.启动5.访问6.查看默认密码7.创建私库8.修改代码配置文件9.在maven 的setting.xml中配置私库的账号密码10.运行manve 【deploy】命令测试11.maven项目引用私库12. 重新加载mave…

指针进阶(4)看一下这些与指针有关的题你都会做吗?

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

智慧公厕的三大特点:信息化、数字化、智慧化

智慧公厕是以物联网、互联网、大数据、云计算等先进技术为支撑&#xff0c;对公共厕所的使用、运营、管理、养护进行全方位高效应用的创新型公厕。它具有三大显著特点&#xff1a;&#xff08;ZonTree中期&#xff09;信息化、数字化和智慧化。本文以智慧公厕源头实力厂家广州中…

Vision Transformer结构解析

Vision Transformer结构解析 ViT简介ViT参数量ViT三大模块ViT图像预处理模块——PatchEmbed多层Transformer Encoder模块MLP&#xff08;FFN&#xff09;模块 基本的Transformer模块Vision Transformer类的实现Transformer知识点网络结构计算复杂度对比Transformer的参数量和计…

几种电脑提示mfc140.dll丢失的解决方法,以及如何预防mfc140.dll丢失

mfc140.dll真是一个超级关键的动态链接库文件&#xff01;一旦这个文件不翼而飞&#xff0c;可能会导致一些程序无法顺利运行&#xff0c;甚至给系统带来麻烦。但别担心&#xff01;遇到mfc140.dll文件丢失的情况&#xff0c;我们有一堆应对措施可以立马施行&#xff0c;确保问…

类和对象-C++运算符重载

#include <iostream> #include <string> using namespace std;class Person { public:Person(int age){m_Agenew int (age);}~Person(){if(m_Age!NULL){delete m_Age;m_AgeNULL;}}//重载 赋值运算符Person& operator (Person &p){//编译器提供深拷贝//m_Ag…

143.和弦是什么?和声是什么?三和弦

内容参考于&#xff1a; 三分钟音乐社 上一个内容&#xff1a;142.音程的构唱练习 和弦的定义&#xff1a; 一个音可以把它称为单音 两个音可以把它称为音程 更多的音&#xff0c;通俗的定义上&#xff0c;三个音或者三个以上的音构成的集体就可以叫做和弦&#xff0c;这些音…

FPGA IBUFG

IBUFG和IBUFGDS的输入端仅仅与芯片的专用全局时钟输入管脚有物理连接&#xff0c;与普通IO和其它内部CLB等没有物理连接。 所以&#xff0c;IBUFG输入的不能直接接另外信号。 GTH transceiver primitives are called GTHE3_COMMON and GTHE3_CHANNEL in UltraScale FPGAs, an…