总结6..

背包问题的解决过程

在解决问题之前,为描述方便,首先定义一些变量:Vi表示第 i 个物品的价值,Wi表示第 i 个物品的体积,定义V(i,j):当前背包容量 j,前 i 个物品最佳组合对应的价值,同时背包问题抽象化(X1,X2,…,Xn,其中 Xi 取0或1,表示第 i 个物品选或不选)。

1、建立模型,即求max(V1X1+V2X2+…+VnXn);

2、寻找约束条件,W1X1+W2X2+…+WnXn<capacity;

3、寻找递推关系式,面对当前商品有两种可能性:

包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,即V(i,j)=V(i-1,j);

还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个,即V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)}。

其中V(i-1,j)表示不装,V(i-1,j-w(i))+v(i) 表示装了第i个商品,背包容量减少w(i),但价值增加了v(i);

由此可以得出递推关系式:

j<w(i) V(i,j)=V(i-1,j)

j>=w(i) V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)}

 #include <stdio.h>

int main() {

    // 定义数组a用于存储每个节点的权值,数组b作为邻接矩阵存储节点间的连接关系

    // dp数组用于存储从每个节点出发能得到的最大权值和,d数组用于记录路径

    int a[30], b[30][30] = {0}, n, dp[30] = {0}, d[30] = {0};

    // 读取节点的数量n

    scanf("%d", &n);

    // 读取每个节点的权值,存储到数组a中,这里从a[1]到a[n]存储有效数据

    for (int i = 1; i <= n; i++)

        scanf("%d", &a[i]);

 

    // 读取邻接矩阵b的上三角部分,表示节点之间的连接关系

    // b[i][j]为1表示节点i到节点j有一条边

    for (int i = 1; i < n; i++) {

        for (int j = i + 1; j <= n; j++) {

            scanf("%d", &b[i][j]);

        }

    }

 

    // 初始化dp[n]为节点n的权值,因为从节点n出发没有后续节点,所以它的最大权值和就是自身权值

    dp[n] = a[n];

    // 记录当前最大权值和对应的节点编号,初始化为n

    int maxi = n;

 

    // 从倒数第二个节点开始向前遍历,计算从每个节点出发的最大权值和

    for (int i = n - 1; i >= 1; i--) {

        // 初始化dp[i]为节点i的权值

        dp[i] = a[i];

        // 初始化d[i]为0,表示当前还没有找到后续能使权值和更大的节点

        d[i] = 0;

 

        // 遍历节点i之后的所有节点j,寻找从节点i到节点j的路径

        for (int j = i + 1; j <= n; j++) {

            // 如果节点i到节点j有边,并且通过节点j能使从节点i出发的权值和更大

            if (b[i][j] == 1 && dp[j] + a[i] > dp[i]) {

                // 更新从节点i出发的最大权值和

                dp[i] = dp[j] + a[i];

                // 记录使权值和最大的后续节点j

                d[i] = j;

            }

        }

 

        // 如果当前节点i的最大权值和大于之前记录的最大权值和

        if (dp[i] > dp[maxi])

            // 更新最大权值和对应的节点编号为i

            maxi = i;

    }

 

    // 从最大权值和对应的节点maxi开始,按照记录的路径输出路径上的节点

    int t = maxi;

    while (t > 0) {

        printf("%d ", t);

        t = d[t];

    }

    printf("\n");

    // 输出从最大权值和对应的节点出发能得到的最大权值和

    printf("%d", dp[maxi]);

    return 0;

}

 #include <stdio.h>

 

// 定义一个函数max,用于返回两个整数中的较大值

int max(int a, int b) {

    return a > b? a : b;

}

 

int main() {

    // t表示背包的容量,m表示物品的数量

    // w数组用于存储每个物品的重量,v数组用于存储每个物品的价值

    // dp数组是动态规划的核心数组,dp[i][j]表示考虑前i个物品,背包容量为j时能获得的最大价值

    int t, m, w[103], v[103], dp[103][1003];

 

    // 读取背包的容量t和物品的数量m

    scanf("%d %d", &t, &m);

 

    // 依次读取每个物品的重量和价值,并存储到w数组和v数组中

    for (int i = 1; i <= m; i++) {

        scanf("%d %d", &w[i], &v[i]);

    }

 

    // 动态规划核心部分,通过两层循环填充dp数组

    // 外层循环遍历每个物品,从第1个物品到第m个物品

    for (int i = 1; i <= m; i++) {

        // 内层循环从背包容量t开始递减到0,用于计算在不同背包容量下的最大价值

        for (int j = t; j >= 0; j--) {

            // 如果当前背包容量j大于等于当前物品i的重量w[i],说明可以放入该物品

            if (j >= w[i]) {

                // 此时有两种选择:放入物品i,价值为dp[i - 1][j - w[i]] + v[i];不放入物品i,价值为dp[i - 1][j]

                // 取两者中的较大值作为dp[i][j]的值

                dp[i][j] = max(dp[i - 1][j - w[i]] + v[i], dp[i - 1][j]);

            } else {

                // 如果当前背包容量j小于当前物品i的重量w[i],则无法放入该物品

                // 此时dp[i][j]的值等于不考虑当前物品i时,背包容量为j的最大价值,即dp[i - 1][j]

                dp[i][j] = dp[i - 1][j];

            }

        }

    }

 

    // 输出考虑所有m个物品,背包容量为t时能获得的最大价值

    printf("%d", dp[m][t]);

 

    return 0;

}

 

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

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

相关文章

代码随想录day1

704.二分查找&#xff1a; 1.左闭右闭 int search(vector<int>& nums, int target) {int right nums.size() - 1;int left 0;while(left < right){int middle left ((right - left) >> 1);if(nums.at(middle) target){return middle;}else if(nums[m…

四级词汇第六期

1.accomplish 完成 2.implication 暗示 3.complicated 复杂的 4.extent 范围 5.sufficient 充足的 6.remarkable 引人注目的 7.insight 洞察 8.executive 管理的 9.overlook 俯瞰 忽略 10.urge 渴望 激励 11.urgent 紧急的 12.accumulate 积累 13.appreciate 赏识 …

OpenHarmony OTA升级参考资料记录

OpenHarmony 作为一个开源分布式操作系统,通过其强大的 OTA(Over-The-Air)升级能力,为开发者和厂商提供了一套灵活而安全的系统升级方案。 OTA升级方式 根据升级包的应用方式,OpenHarmony 的 OTA 升级可以分为两种:本地升级和网络OTA升级。 本地升级 本地升级是将已制作…

【数据结构篇】顺序表 超详细

目录 一.顺序表的定义 1.顺序表的概念及结构 1.1线性表 2.顺序表的分类 2.1静态顺序表 2.2动态顺序表 二.动态顺序表的实现 1.准备工作和注意事项 2.顺序表的基本接口&#xff1a; 2.0 创建一个顺序表 2.1 顺序表的初始化 2.2 顺序表的销毁 2.3 顺序表的打印 3.顺序…

SDL2基本的绘制流程与步骤

SDL2(Simple DirectMedia Layer 2)是一个跨平台的多媒体库,它为游戏开发和图形应用提供了一个简单的接口,允许程序直接访问音频、键盘、鼠标、硬件加速的渲染等功能。在 SDL2 中,屏幕绘制的流程通常涉及到窗口的创建、渲染目标的设置、图像的绘制、事件的处理等几个步骤。…

上位机工作感想-2024年工作总结和来年计划

随着工作年限的增增长&#xff0c;发现自己越来越不喜欢在博客里面写一些掺杂自己感想的东西了&#xff0c;或许是逐渐被工作逼得“成熟”了吧。2024年&#xff0c;学到了很多东西&#xff0c;做了很多项目&#xff0c;也帮别人解决了很多问题&#xff0c;唯独没有涨工资。来这…

阿里云-银行核心系统转型之业务建模与技术建模

业务领域建模包括业务建模和技术建模&#xff0c;整体建模流程图如下&#xff1a; 业务建模包括业务流程建模和业务对象建模 业务流程建模&#xff1a;通过对业务流程现状分析&#xff0c;结合目标核心系统建设能力要求&#xff0c;参考行业建 模成果&#xff0c;形成结构化的…

Unity3D基于Unity整合BEPUphysicsint物理引擎实战详解

引言 Unity3D是一款流行的游戏引擎&#xff0c;提供了丰富的功能和工具&#xff0c;使开发者能够轻松创建各种类型的游戏。其中&#xff0c;帧同步技术是游戏开发中至关重要的一环&#xff0c;它能确保多个玩家在同一时间内看到的游戏状态是一致的。BEPUphysicsint是一个基于U…

【C++笔记】红黑树封装map和set深度剖析

【C笔记】红黑树封装map和set深度剖析 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】红黑树封装map和set深度剖析前言一. 源码及框架分析1.1 源码框架分析 二. 模拟实现map和set2.1封装map和set 三.迭代器3.1思路…

win32汇编环境,怎么得到磁盘的盘符

;运行效果 ;win32汇编环境,怎么得到磁盘的盘符 ;以下代码主要为了展示一下原理&#xff0c;应用GetLogicalDrives、GetLogicalDriveStrings函数、屏蔽某些二进制位、按双字节复制内容等。以下代码最多查8个盘&#xff0c;即返回值中的1个字节的信息 ;直接抄进RadAsm可编译运行。…

MongoDB vs Redis:相似与区别

前言 在当今的数据库领域&#xff0c;MongoDB 和 Redis 都是备受关注的非关系型数据库&#xff08;NoSQL&#xff09;&#xff0c;它们各自具有独特的优势和适用场景。本文将深入探讨 MongoDB 和 Redis 的特点&#xff0c;并详细对比它们之间的相似之处和区别&#xff0c;帮助…

mybatis(19/134)

大致了解了一下工具类&#xff0c;自己手敲了一边&#xff0c;java的封装还是真的省去了很多麻烦&#xff0c;封装成一个工具类就可以不用写很多重复的步骤&#xff0c;一个工厂对应一个数据库一个environment就好了。 mybatis中调用sql中的delete占位符里面需要有字符&#xf…

重学SpringBoot3-WebClient配置与使用详解

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞??收藏评论 重学SpringBoot3-WebClient配置与使用详解 1. 简介2. 环境准备 2.1 依赖配置 3. WebClient配置 3.1 基础配置3.2 高级配置3.3 retrieve()和exchange()区别 4. 使用示例 4.1 基本请求操…

.Net Core微服务入门全纪录(二)——Consul-服务注册与发现(上)

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…

Spark Streaming的核心功能及其示例PySpark代码

Spark Streaming是Apache Spark中用于实时流数据处理的模块。以下是一些常见功能的实用PySpark代码示例&#xff1a; 基础流处理&#xff1a;从TCP套接字读取数据并统计单词数量 from pyspark import SparkContext from pyspark.streaming import StreamingContext# 创建Spar…

深度学习系列75:sql大模型工具vanna

1. 概述 vanna是一个可以将自然语言转为sql的工具。简单的demo如下&#xff1a; !pip install vanna import vanna from vanna.remote import VannaDefault vn VannaDefault(modelchinook, api_keyvanna.get_api_key(my-emailexample.com)) vn.connect_to_sqlite(https://va…

【线性代数】列主元法求矩阵的逆

列主元方法是一种用于求解矩阵逆的数值方法&#xff0c;特别适用于在计算机上实现。其基本思想是通过高斯消元法将矩阵转换为上三角矩阵&#xff0c;然后通过回代求解矩阵的逆。以下是列主元方法求解矩阵 A A A 的逆的步骤&#xff1a; [精确算法] 列主元高斯消元法 步骤 1&am…

[0242-06].第06节:SpringBoot对SpringMVC的自动配置

SpringBoot学习大纲 一、基于SpringBoot搭建Web工程&#xff1a; 1.1.编码实现步骤&#xff1a; a.创建SpringBoot项目 b.选中依赖&#xff1a;选中我们所需要的模块 1.2.SSM中的WEB开发配置与SpringBoot中WEB开发自动配置对比&#xff1a; a.SSM中的WEB开发&#xff1a; 1…

【21】Word:德国旅游业务❗

目录 题目 NO1.2.3 NO4 NO5.6 NO7 NO8.9.10.11 题目 NO1.2.3 F12&#xff1a;另存为布局→页面设置→页边距&#xff1a;上下左右选中“德国主要城市”→开始→字体对话框→字体/字号→文本效果&#xff1a;段落对话框→对齐方式/字符间距/段落间距 NO4 布局→表对话框…

什么是软件架构

什么是软件架构 程序员说&#xff0c;软件架构是要决定编写哪些C程序或OO类、使用哪些库和框架 程序经理说&#xff0c;软件架构就是模块的划分和接口的定义 系统分析员说&#xff0c;软件架构就是为业务领域对象的关系建模 配置管理员说&#xff0c;软件架构就是开发出来的…