c++中的斐波那契数列(Fibonacci Sequence)和背包问题(Knapsack Problem)

前言

hello,大家好啊,我是文宇,不是文字,是文宇哦。

斐波那契数列(Fibonacci Sequence)

斐波那契数列(Fibonacci Sequence)是一个经典的数学问题,其中每个数都是前两个数的和。在C++中,我们可以使用多种算法来计算斐波那契数列,下面我将详细介绍每个算法的实现和优缺点。

递归算法

递归算法是最直观和简单的方法来实现斐波那契数列。通过递归调用函数来计算每一个数。具体实现如下:

int fibonacci(int n) {if (n <= 1) {return n;}return fibonacci(n - 1) + fibonacci(n - 2);
}

递归算法的优点是简洁易懂,容易理解。但是它的缺点是重复计算量大,在计算较大的斐波那契数时,可能会导致性能问题。

迭代算法

 为了避免递归算法的重复计算,我们可以使用迭代算法来计算斐波那契数列。迭代算法的基本思路是从前往后依次计算每一个数,保存中间结果。具体实现如下:

int fibonacci(int n) {if (n <= 1) {return n;}int a = 0;int b = 1;int c;for (int i = 2; i <= n; i++) {c = a + b;a = b;b = c;}return c;
}

迭代算法的优点是避免了递归算法的重复计算,性能相对较好。但是它的缺点是需要编写较多的代码,可读性稍差。

数组算法

 我们还可以使用数组来保存斐波那契数列的中间结果,以进一步提高性能。具体实现如下:

int fibonacci(int n) {if (n <= 1) {return n;}int* fib = new int[n + 1];fib[0] = 0;fib[1] = 1;for (int i = 2; i <= n; i++) {fib[i] = fib[i - 1] + fib[i - 2];}int result = fib[n];delete[] fib;return result;
}

数组算法的优点是性能较好,同时代码相对简单。但是它的缺点是需要额外的内存空间来保存数组,可能导致内存泄漏。

公式算法

在斐波那契数列的研究中,我们还发现了一个通项公式来直接计算第n个斐波那契数。具体公式如下:

int fibonacci(int n) {double goldenRatio = (1 + sqrt(5)) / 2;return round(pow(goldenRatio, n) / sqrt(5));
}

公式算法的优点是计算简单快速,但是它的缺点是可能会有精度问题,同时不太容易理解。

综上所述,以上四种算法都可以用来实现斐波那契数列。具体选择哪种算法取决于实际需求和性能要求。如果不考虑性能,递归算法是最简单直观的方法;如果性能较重要,迭代算法和数组算法可以提供较好的性能;如果要求精确计算,公式算法是一个很好的选择。

背包问题(Knapsack Problem)

背包问题(Knapsack Problem)是一个经典的组合优化问题,在计算机科学领域中被广泛研究和应用。它的基本问题可以描述为,给定一个背包的容量和一系列物品的重量和价值,如何选择物品放入背包中,使得背包中物品的总价值最大。

在C++中,我们可以使用多种算法来解决背包问题,下面我将详细介绍每个算法的实现和优缺点。

  1. 0/1背包问题: 0/1背包问题是背包问题中最基本的形式,其中每个物品要么完全放入背包,要么完全不放入。我们可以使用动态规划来解决0/1背包问题。具体算法如下:
int knapsack01(vector<int>& weights, vector<int>& values, int capacity) {int n = weights.size();vector<vector<int>> dp(n + 1, vector<int>(capacity + 1, 0));for (int i = 1; i <= n; i++) {for (int j = 1; j <= capacity; j++) {if (weights[i - 1] > j) {dp[i][j] = dp[i - 1][j];} else {dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1]);}}}return dp[n][capacity];
}

0/1背包问题的关键是构建一个二维的动态规划数组,利用前一个状态的结果来更新当前状态。它的优点是能够得到精确的解,但是它的缺点是时间复杂度较高,需要O(n * capacity)的时间和空间。

  1. 完全背包问题: 完全背包问题是背包问题中的一个变种,其中每个物品可以无限次地放入背包。我们同样可以使用动态规划来解决完全背包问题。具体算法如下:
int knapsackComplete(vector<int>& weights, vector<int>& values, int capacity) {int n = weights.size();vector<int> dp(capacity + 1, 0);for (int i = 0; i < n; i++) {for (int j = weights[i]; j <= capacity; j++) {dp[j] = max(dp[j], dp[j - weights[i]] + values[i]);}}return dp[capacity];
}

完全背包问题与0/1背包问题的区别在于内层循环的顺序,我们需要从小到大遍历容量,而不是从大到小。它的优点是时间复杂度相对较低,只需要O(n * capacity)的时间和O(capacity)的空间。

  1. 多重背包问题: 多重背包问题是背包问题中的另一种变种,其中每个物品有一个数量限制。我们可以使用动态规划来解决多重背包问题,类似于0/1背包问题。具体算法如下:
int knapsackMultiple(vector<int>& weights, vector<int>& values, vector<int>& quantities, int capacity) {int n = weights.size();vector<vector<int>> dp(n + 1, vector<int>(capacity + 1, 0));for (int i = 1; i <= n; i++) {for (int j = 1; j <= capacity; j++) {for (int k = 0; k <= quantities[i - 1] && k * weights[i - 1] <= j; k++) {dp[i][j] = max(dp[i][j], dp[i - 1][j - k * weights[i - 1]] + k * values[i - 1]);}}}return dp[n][capacity];
}

多重背包问题与0/1背包问题的区别在于内层循环的次数,我们需要遍历每个物品的数量限制。它的优点是能够解决具有数量限制的背包问题,但是它的缺点是时间复杂度较高,需要O(n * quantity * capacity)的时间和空间。

  1. 分数背包问题: 分数背包问题是背包问题中的一种特殊情况,其中每个物品可以被分割成任意大小的部分。我们可以使用贪心算法来解决分数背包问题,基于物品的单位价值进行排序,然后依次选择单位价值最高的物品放入背包中,直到背包没有空间为止。具体算法如下:
double knapsackFractional(vector<int>& weights, vector<int>& values, int capacity) {int n = weights.size();vector<pair<double, int>> ratios(n);for (int i = 0; i < n; i++) {ratios[i] = {static_cast<double>(values[i]) / weights[i], i};}sort(ratios.rbegin(), ratios.rend()); // 按照单位价值降序排序double result = 0.0;for (int i = 0; i < n; i++) {int index = ratios[i].second;if (weights[index] <= capacity) {result += values[index];capacity -= weights[index];} else {result += capacity * ratios[i].first;break;}}return result;
}

分数背包问题的优点是时间复杂度较低,只需要O(n * log(n))的时间和O(n)的空间,但是它的缺点是不能得到精确的解。

综上所述,以上四种算法都可以用来解决不同形式的背包问题。具体选择哪种算法取决于实际需求和性能要求。如果物品数量较少且要求精确解,可以使用0/1背包算法;如果物品数量较多或者需要更高的性能,可以使用完全背包算法;如果需要考虑物品的数量限制,可以使用多重背包算法;如果物品可以被分割成任意大小,可以使用分数背包算法。

结语

今天的算法是动态规划,脑子有点不好使了。

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

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

相关文章

24年第三届钉钉杯大学生大数据挑战赛浅析

需要完整资料&#xff0c;请关注WX&#xff1a;“小何数模”&#xff01; 本次钉钉杯大数据挑战赛的赛题已正式出炉&#xff0c;无论是赛题难度还是认可度&#xff0c;该比赛都是仅次于数模国赛的独一档&#xff0c;可以用于国赛前的练手训练。考虑到大家解题实属不易&#xf…

气膜足球馆:经济高效的室内足球场馆解决方案—轻空间

如果你有一片足球场&#xff0c;想要建一个室内的足球馆&#xff0c;为什么不考虑一下气膜建筑呢&#xff1f;气膜建筑以其独特的优势和高性价比&#xff0c;成为现代体育场馆建设中的一匹黑马。它不仅具有传统建筑无法比拟的经济效益和快速施工优势&#xff0c;还在智能控制、…

vue实现电子签名、图片合成、及预览功能

业务功能&#xff1a;电子签名、图片合成、及预览功能 业务背景&#xff1a;需求说想要实现一个电子签名&#xff0c;然后需要提供一个预览的功能&#xff0c;可以查看签完名之后的完整效果。 需求探讨&#xff1a;后端大佬跟我说&#xff0c;文档我返回给你一个PDF的oss链接…

7.27扣...

知识点补充&#xff1a; 1.StringBuilder StringBuilder 类在 Java 中是一个可变字符序列。与 String 类不同&#xff0c;StringBuilder 可以在创建之后被修改。这意味着你可以向 StringBuilder 对象追加、插入或删除字符&#xff0c;而不需要创建新的对象&#xff08;辅助数…

企业公户验证API如何使用JAVA、Python、PHP语言进行应用

在纷繁复杂的金融与商业领域&#xff0c;确保每笔交易的安全与合规是至关重要的。而企业公户验证API&#xff0c;正是这样一位默默守护的数字卫士&#xff0c;它通过智能化的手段&#xff0c;简化了企业对公账户验证流程&#xff0c;让繁琐的审核变得快捷且可靠。 什么是企业公…

chrome浏览器驱动(所有版本)

chrome浏览器驱动 114之前版本 https://chromedriver.storage.googleapis.com/index.html 125以后 125以后版本下载链接在此&#xff0c;只有后面status是绿色对勾的才可以下载&#xff0c;驱动大版本一致就可以使用&#xff0c;不需版本号一模一样&#xff1b;下载所需版本只…

语言转文字

因为工作原因需要将语音转化为文字&#xff0c;经常搜索终于找到一个免费的好用工具&#xff0c;记录下使用方法 安装Whisper 搜索Colaboratory 右上方链接服务 执行 !pip install githttps://github.com/openai/whisper.git !sudo apt update && sudo apt install f…

在appium中,如何通过匹配图片来进行断言?

在Appium中进行图片匹配断言&#xff0c;可以使用OpenCV来实现。以下是使用Appium和OpenCV进行图片匹配断言的示例代码。 首先&#xff0c;需要确保安装了必要的库&#xff1a; pip install opencv-python-headless pip install opencv-python pip install numpy然后&#xf…

【区块链+绿色低碳】绿色电力分布式身份管理系统 | FISCO BCOS应用案例

目前&#xff0c;绿色电力场景在身份管理方面存在一些痛点&#xff0c;如&#xff1a;绿色电力交易场景中&#xff0c;主体地理位置分散&#xff0c;主体类型&#xff08;人、机、 物&#xff09;差异较大&#xff0c;主体身份认证和管理方式要求差异较大&#xff1b;在着力发展…

高性能 Java 本地缓存 Caffeine 框架介绍及在 SpringBoot 中的使用

在现代应用程序中&#xff0c;缓存是一种重要的性能优化技术&#xff0c;它可以显著减少数据访问延迟&#xff0c;降低服务器负载&#xff0c;提高系统的响应速度。特别是在高并发的场景下&#xff0c;合理地使用缓存能够有效提升系统的稳定性和效率。 Caffeine 是一个高性能的…

《程序猿入职必会(4) · Vue 完成 CURD 案例 》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

Eclipse的一些使用

出错的原因: eclipse中&#xff0c;当声明了变量&#xff0c;没有进行初始化&#xff0c;然后在方法中引用该变量的时候&#xff0c;就会报出如下错误&#xff1a; The local variable XXX may not have been initialized意思是该变量没有进行初始化&#xff0c;解决这个错误就…

【C++刷题】优选算法——队列+宽搜

N 叉树的层序遍历 vector<vector<int>> levelOrder(Node* root) {vector<vector<int>> ret;if (root nullptr) return ret;queue<Node*> q;q.push(root);ret.push_back({root->val});int size 1;while (!q.empty()) {vector<int> v…

【机器学习】Jupyter Notebook如何使用之基本步骤和进阶操作

引言 Jupyter Notebook 是一个交互式计算环境&#xff0c;它允许创建包含代码、文本和可视化内容的文档 文章目录 引言一、基本步骤1.1 启动 Jupyter Notebook1.2 使用 Jupyter Notebook 仪表板1.3 在笔记本中工作1.4 常用快捷键1.5 导出和分享笔记本 二、进阶用法2.1 组织笔…

CSS性能优化:从加载速度到渲染效率的全方位提升

在快节奏的互联网环境中&#xff0c;网页的加载速度和渲染效率直接关系到用户体验和搜索引擎排名。CSS作为网页样式的主要描述语言&#xff0c;其性能优化同样不容忽视。本文将介绍一系列CSS性能优化的策略&#xff0c;帮助开发者从加载速度到渲染效率实现全方位的提升。 1. 压…

从零开始学习网络安全渗透测试之基础入门篇——(二)Web架构前后端分离站Docker容器站OSS存储负载均衡CDN加速反向代理WAF防护

Web架构 Web架构是指构建和管理Web应用程序的方法和模式。随着技术的发展&#xff0c;Web架构也在不断演进。当前&#xff0c;最常用的Web架构包括以下几种&#xff1a; 单页面应用&#xff08;SPA&#xff09;&#xff1a; 特点&#xff1a;所有用户界面逻辑和数据处理都包含…

vscode container

附加到已有容器 终端进程“/sbin/nologin”启动失败(退出代码: 1)。 原因是因为默认vscode container 使用default 这个用户进行登陆。而这个default 是使用shell 的&#xff08;在/etc/passwd中配置&#xff09;。我们要修改vscode 行为&#xff0c;添加默认的bash 终端启动…

劝你不要上自动化立体库,非要上,砸锅了吧

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 在当今这个科技日新月异的时代&#xff0c;自动化立体库作为仓储物流领域的佼佼者&#xff0c;以其高效、精准、节省人力的优势&#xff0c;吸引…

Windows下帆软BI(finebi)单机部署移植(Tomcat)攻略

一、基础环境 操作系统&#xff1a;Windows 10 64bit 帆软BI 版本&#xff1a;V9.0/V10.0 HTTP工具&#xff1a;Tomcat 外置数据库&#xff1a;Oracle 11g 实验内容&#xff1a;将已经部署好的帆软BI从一台电脑移植到另一台电脑 二、前期准备 1、做好外置数据库移植&…

spring —— IoC 容器(一)

IoC 不是一种技术&#xff0c;而是一种设计思想&#xff0c;旨在降低代码之间的耦合性。Spring 通过 IoC 容器管理所有 Java 对象的实例化和初始化&#xff0c;控制对象与对象之间的依赖关系。 一、基于 XML 管理 bean &#xff08;一&#xff09;通过 XML 获取 bean public…