动态规划01背包问题

news2024/11/26 11:36:47

01背包问题

假设你是一名经验丰富的探险家,背着背包来到野外进行日常探险。天气晴朗而不燥热,山间的风夹杂着花香,正当你欣赏这世外桃源般的美景时,突然,你发现了一个洞穴,这个洞穴外表看起来其貌不扬,但凭借着惊为天人的直觉,这个洞穴不简单。于是,你开始往洞穴内探索,希望能发现一些有意思的东西。终于,皇天不负有心人,你在洞穴的尽头,发现了一堆珠宝,凭借你惊人的阅历,一眼便看出了它们各自的价值,心想着下下下下下下下下半辈子都有着落了。然而,天有不测风云,正准备将它们收入囊中,却不小心触碰到一个防御机关,洞穴马上就要崩塌了。在此危机时刻,你只有一个背包,你必须尽快做出抉择,从中选择最值钱的珠宝塞到你的背包,让背包中珠宝的总价值最大。好了好了,啰里啰嗦了大半天,我还是来精简一下问题吧。简而言之,你只有一个容量有限的背包,总容量为c,有n个可待选择的物品,每个物品只有一件,它们都有各自的重量和价值,你需要从中选择合适的组合来使得你背包中的物品总价值最大。问题分析:那还不简单,不管是什么,先往背包里塞,塞满赶紧走,狗命要紧,狗命要紧。。。好了好了,开个玩笑,言归正传。简单起见,我们来将上面的问题具体化,举一个更具体的栗子:假设有4个物品,它们的价值(v)和重量(w)如下图:
请添加图片描述
背包总容量为10,现在要从中选择物品装入背包中,要求物品的重量不能超过背包的容量,并且最后放在背包中物品的总价值最大。emmm,等等,为什么叫做0/1背包呢?为什么不叫1/2背包,2/3背包???仔细想想,这里每个物品只有一个,对于每个物品而言,只有两种选择,盘它或者不盘,盘它记为1,不盘记为0,我们不能将物品进行分割,比如只拿半个是不允许的。这就是这个问题被称为0/1背包问题的原因。所以究竟选还是不选,这是个问题。让我们先来体验一下将珠宝装入背包的感觉,为了方便起见,用xi代表第i个珠宝的选择(xi = 1 代表选择该珠宝,0则代表不选),vi代表第i个珠宝的价值,wi代表第i个珠宝的重量。于是我们就有了这样的限制条件:
请添加图片描述
我们的初始状态是背包容量为10,背包内物品总价值为0,接下来,我们就要开始做选择了。对于1号珠宝,当前容量为10,容纳它的重量2绰绰有余,因此有两种选择,选它或者不选。我们选择一个珠宝的时候,背包的容量会减少,但是里面的物品总价值会增加。就像下面这样:
请添加图片描述
这样就分出了两种情况,我们继续进行选择,如果我们选择了珠宝1,那么对于珠宝2,当前剩余容量为8,大于珠宝2的容量3,因此也有两种选择,选或者不选。
请添加图片描述
现在,我们得到了四个可能结果,我们每做出一个选择,就会将上面的每一种可能分裂成两种可能,后续的选择也是如此,最终,我们会得到如下的一张决策图:
请添加图片描述
这里被涂上色的方框代表我们的最终待选结果,本来应该有16个待选结果,但有三个结果由于容量不足以容纳下最后一个珠宝,所以就没有继续进行裂变。然后,我们从这些结果中,找出价值最大的那个,也就是13,这就是我们的最优选择,根据这个选择,依次找到它的所有路径,便可以知道该选哪几个珠宝,最终结果是:珠宝4,珠宝2,珠宝1。简单的看,对于每个物品,无外乎两种可能:选,或者不选。不选的话,背包的容量不变,最大价值还是之前的价值;选的话,背包的容量变小,价值变大。最优方案就是比较这两种方案,哪个会更好些:
**

01背包问题

[算法分析]

定义状态∶dp[i][j]:有i件物品,背包容量为j的情况下存储的最大价值w[i]第i件物品的重量,c背包总容量,j表示背包实时容量,也就是0到c之间的容量,v[i]第i件物品的价值如果w[i]>j:放不下,最大价值为i-1件物品讨论时的最大价值,即dp[i-1][j];如果w[i]<=j:放得下:
选上: 剩余容量:j-w[i],最大价值:v[i] + (i-1件物品,容量在j- w[i]的情况下最大价值),即v[i]+dp[i-1][j-w[i]];不选: 最大价值:i-1件物品讨论时的最大价值,即dp[i-1][j];所以动态转移方程:dp[i][j]=max(dp[i-1][j],v[i]+dp[i-1][j-w[i]])


```cpp
#include<bits/stdc++.h>
using namespace std;
/*
动态转移方程:dp[i][j]=max(dp[i-1][j],v[i]+dp[i-1][j-w[i]]) 
*/
//c代表背包容量
//dp[i][j]:有i件物品,背包容量为j的情况下存储的最大价值
int c,dp[40][210],w[40],v[40],i,j,n; 
int main(){
    cin >> c>>n;
    for(i=1;i<=n;i++){
        cin >> w[i]>>v[i];
    }
    //递推求dp数组
    for(i=1;i<=n;i++){
        //在i件物品,讨论背包容量j分别是1-c的情况下,最大价值
        //j代表背包容量
        for(j=1;j<=c;j++){
            //如果能够放得下
            if(w[i]<=j){
                dp[i][j]=max(dp[i-1][j],v[i]+dp[i-1][j-w[i]]);
            } else{
                //放不下
                dp[i][j]=dp[i-1][j]; 
            }
        }   
    } 
    cout << dp[n][c];
    return 0;
}


背包

有个背包可承受重量N,现有T件物品,每件物品重量为wi​,价值为vi​,每件物品只有一个,这个背包可以装载物品的最大价值是多少?输入格式第一行,两个整数,分别表示N和T,用空格隔开(N≤1000,T≤100)接下来T行,每行两个整数,分别表示T件物品的重量wi​和价值vi​(1≤wi​,vi​≤100)输出格式一行,表示这个背包可以装载物品的最大价值输入输出样列
输入样例1:
100 577 9222 2229 8750 4699 90
输出样例1:

133

[算法分析]定义状态∶d(i,j)表示为前i个物品分配j容量的背包,可以获得的最大价值。对于物品i有2种选择∶选择1∶ 不选择将i放入背包∶ d(i, j) = d(i-1,j)。选择2∶选择将i放入背包d(i,j)=d(i-1,j-wi​)+vi​(j>=wi​)。状态转移方程∶ d(i,j)= max(d(i-1,j), d(i-1,j-wi​)+vi​)。

#include<bits/stdc++.h>
using namespace std;
const int N=1005,T=105;
//dp[i][j]:有i件物品,背包容量为j的情况下存储的最大价值
int dp[T][N],v[T],w[T];
int main()
{
    int n,t;
    cin>>n>>t;
    for(int i=1;i<=t;i++)
    {
        cin>>w[i]>>v[i];
    }
    for(int i=1;i<=t;i++)  //t件物品
    {
        for(int j=1;j<=n;j++) 
        //在i件物品,讨论背包容量j分别是1-n的情况下,最大价值
        //j代表背包容量
        {
            if(j>=w[i])//放得下
                dp[i][j]=max(dp[i-1][j],v[i]+dp[i-1][j-w[i]]);
            else//放不下
                dp[i][j]=dp[i-1][j];
        }
    }
    cout<<dp[t][n];
    return 0;
} 

————未完

一定拖更

在这里插入图片描述

好了,背包问题(1·)就到这——别走第二期动态规划下期更新!!!o( ̄▽ ̄)d

播放量到150下期继续

不见不散

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

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

相关文章

UE动画状态机的事件触发顺序测试

正常A状态过渡到B状态的事件顺序&#xff1a; 整个流程为&#xff1a; 调用B状态的On Become Relevant事件调用B状态的On Update事件调用A状态的Left State Event事件调用B状态的Entered State Event事件调用B状态的Start Transition Event事件调用B状态的End Transition Even…

网络安全:通过445端口暴力破解植入木马。

网络安全&#xff1a;通过445端口暴力破解植入木马。 木马制作工具&#xff0c;如&#xff1a;灰鸽子等等 445端口是文件共享端口。可以进入对方文件硬盘进行植入木马&#xff1a; 使用文件共享进入对方磁盘&#xff1a; 在cmd输入net use \\x.x.x.x\ipc$ 之后会让你输入账号…

Vue——组合式函数

目录 什么是“组合式函数”&#xff1f;​ 鼠标跟踪器示例​ 异步状态示例​ 约定和最佳实践​ 命名​ 输入参数​ 返回值​ 副作用​ 使用限制​ 通过抽取组合式函数改善代码结构 选项式 API 中使用组合式函数​ 与其他模式的比较​ 和 Mixin 的对比​ 和无渲染…

mybatis逆向生成器

目录 官网xml pom引入 在resources新建generatorConfig.xml xml修改 生成 官网xml MyBatis Generator Core – MyBatis Generator XML Configuration File Reference pom引入 <!-- mybatis逆向生成器 --><dependency><groupId>org.mybatis.gener…

anaconda 共享虚拟环境

需求背景 A,B,C… 多台服务器。 有一个公共的NAS服务器N&#xff0c;存储所有数据资料。 N分别挂载到A,B,C…服务器上&#xff0c;便于所有服务器访问数据。 挂载路径在所有服务器上统一为/nas/。 现状&#xff1a; A,B,C&#xff0c;… 上分别安装anaconda&#xff0c;分别创…

网络钓鱼仍然是安全行业的祸害

随着网络犯罪分子采用更先进的方法&#xff0c;网络钓鱼诈骗继续构成重大风险。 根据 Zscaler 最新发布的 2023 ThreatLabz 网络钓鱼报告&#xff0c;随着网络钓鱼工具包和ChatGPT等人工智能 (AI) 工具的广泛使用&#xff0c;网络犯罪分子比以往任何时候都更容易创建有针对性的…

数字图像处理-matlab图像内插

matlab图像内插 最近邻插值双线性插值双三次插值总结 最近邻插值 目标各像素点的灰度值代替源图像中与其最邻近像素的灰度值 参考博客 假设一个2X2像素的图片采用最近邻插值法需要放大到4X4像素的图片&#xff0c;右边该为多少&#xff1f; 最近邻插值法坐标变换计算公式&…

40.java-单列集合Set(HashSet,LinkedHashSet,TreeSet)

Set集合 1.Set集合特点2.Set集合实现类3. HashSet3.1 底层原理3.1.1 哈希表组成3.1.2 哈希值3.1.3 对象的哈希值特点 3.2 数据添加元素的过程3.3 HashSet的三个问题3.4 实例&#xff1a;去除重复元素 4. LinkedHashSet5. TreeSet5.1 特点5.2 集合默认规则5.3 例子5.4 两种比较规…

泛型——List 优于数组

数组与泛型有很大的不同&#xff1a; 1. 数组是协变的&#xff08;covariant&#xff09; 意思是&#xff1a;如果Sub是Super的子类型&#xff0c;则数组类型Sub[] 是数组类型Super[] 的子类型。 2. 泛型是不变的&#xff08;invariant&#xff09; 对于任何两种不同的类型Ty…

Linux下进程间通信

Linux下进程间通信 进程间通信的目的进程间通信的手段的分类管道什么是管道管道原理匿名管道创建匿名管道文件匿名管道的特点匿名管道的4种场景 有名管道有名管道的创建有名管道总结命名管道的打开规则 system V 共享内存共享内存原理建立通信回收共享内存开始通信命令操作共享…

常用的JVM参数选项

目录 打印设置的XX选项及值 堆、栈、方法区等内存大小设置 OutOfMemory相关的选项 垃圾收集器相关选项 GC日志相关选项 其他参数 通过Java代码获取JVM参数 打印设置的XX选项及值 程序运行时JVM默认设置或用户手动设置的XX选项 -XX:PrintCommandLineFlags 打印所有…

Photoshop如何使用绘画和图像修饰之实例演示?

文章目录 0.引言1.给图像添加渐变色效果2.快速创建一副素描画3.清除图像中多余的景物4.快速融合两张图像5.调整图像光影6.人像面部瑕疵修除7.美化眼睛 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对PS进行了学习&#xff0c;本文通过《Photoshop2021入门教程》及其…

LeetCode 与组合数相关的题目

216. 组合总和 III 方法&#xff1a;递归 class Solution { private:vector<vector<int>> res;vector<int> path;void solve(int k, int goal, int cur, int idx) {if (cur > goal) return;if (path.size() k) {if (cur goal) res.push_back(path);re…

小球下落(dropping balls)uva679

题目描述 原文链接 题目链接 上面中文总结一下&#xff1a; D代表这棵树深度&#xff0c;那么一共就有2^d -1 个结点 每个结点从左到右&#xff0c;从上往下&#xff0c;从1开始递增编号&#xff0c;那么也就是说对于结点k来说&#xff0c;左子结点与右子结点的编号分别为…

C/C++每日一练(20230430)

目录 1. 分割回文串 &#x1f31f;&#x1f31f; 2. 六角填数 ※ 3. 查找书籍 &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 分割回文串 给你一个字符串 s&#x…

unity 渲染性能分析工具

目标 既然要优化&#xff0c;肯定要有个目标&#xff1a; pc上一般要求&#xff1a;一秒渲染60帧 移动端&#xff1a;一秒渲染30帧 这应该是最低的要求&#xff0c;如果游戏运行时&#xff0c;游戏帧率有变化&#xff0c;人眼能够明显的感觉到帧率下降。 优化的首要规则是找到…

CMake | 01 - CMake快速上手(3.26.3)

专栏介绍 本专栏记录了博主入门CMake的笔记。 源码仓库欢迎Star&#xff1a;https://github.com/Mculover666/cmake_study。 一、CMake概述 1. 什么是CMake CMake官网&#xff1a;https://cmake.org/ CMake is an open-source, cross-platform family of tools designed t…

17.计及电转气协同的含碳捕集与垃圾焚烧虚拟电厂优化调度

说明书 MATLAB代码&#xff1a;计及电转气协同的含碳捕集与垃圾焚烧虚拟电厂优化调度 关键词&#xff1a;碳捕集 虚拟电厂 需求响应 优化调度 电转气协同调度 参考文档&#xff1a;《计及电转气协同的含碳捕集与垃圾焚烧虚拟电厂优化调度》完全复现 仿真平台&#xff1a…

【Linux从入门到精通】vim的基本使用各种操作详解

文章目录 一、vim编辑器简单介绍 二、vim编辑器的四种模式 2、1 正常/普通/命令模式(Normal mode) 2、2 插入模式(Insert mode) 2、3 末行模式(last line mode) 三、命令模式的相关操作实例 3、1 光标的相关操作 3、2 文本操作 四、插入模式下的相关操作 五、末行模式下的相关操…

FreeRTOS任务的创建(动态方法和静态方法)

文章目录 前言一、FreeRTOS任务基本概念二、动态创建任务三、静态创建任务四、静态创建任务和动态创建任务的区别五、任务的删除总结 前言 本篇文章将介绍FreeRTOS任务的创建&#xff08;动态方法和静态方法&#xff09;&#xff0c;了解什么是任务和任务的具体创建方法。 一…