「数学::快速幂」矩阵快速幂运算|快速斐波那契数列 / LeetCode 509(C++)

目录

概述

思路

算法过程

复杂度

Code


概述

LeeCode 509:

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1

给定 n ,请计算 F(n) 。

我们介绍过快速幂运算:「数学::快速幂」基本快速幂运算|快速幂取模运算(C++)
快速幂不仅可以用于求数的幂,也可以求矩阵的幂,进而进行将一些递推算法优化成logn算法。


思路

我们首先要求你掌握一些线性代数知识:矩阵的乘法。

矩阵(Matrix)是一个按照方阵排列的复数或实数集合。

矩阵乘法: {

A(mn)*B(st)=C(mt),一个m行n列的矩阵A乘以一个s行t列的矩阵B等于一个m行t列的矩阵的C。

其中,我们要求n必须等于s,否则无法相乘。

接下来我们称矩阵的i行j列为[i][j]。

\sumA[i][k]*B[k][j]=C[i][j]  (\sum:枚举k从1到n)

即:C[i][j]的元素等于A的i行每个元素与B的j行每个对应元素的积的累加和:

      ┌ 2 1 ┐ * ┌ 1 0 ┐ = ┌ 3 3 ┐└ 0 1 ┘   └ 1 3 ┘   └ 1 3 ┘

A矩阵的行数与B矩阵的列数是可以不相等的:

                ┌ 1 1 ┐ [ 1 1 ] * └ 1 0 ┘ = [ 2 1 ]

此外矩阵乘法具有结合律:A*B*.....*B=A*(B)ⁿ。

}

因此考虑:F(n) = F(n - 1) + F(n - 2),我们可以将其递推式写为矩阵乘法:

                      ┌ 1 1 ┐ [ Fn-1 Fn-2 ] * └ 1 0 ┘ = [ Fn Fn-1 ]

也就是说,将初始的\begin{bmatrix} F1 &F0 \end{bmatrix}乘以有系数矩阵\begin{bmatrix} 1& 1\\ 1& 0 \end{bmatrix},就可以递推得到\begin{bmatrix} F2 &F1 \end{bmatrix}

由于矩阵乘法具有结合律:A*B*.....*B=A*(B)ⁿ,我们可以先计算pow(\begin{bmatrix} 1& 1\\ 1& 0 \end{bmatrix},n-1),在执行\begin{bmatrix} F1 &F0 \end{bmatrix}*pow(\begin{bmatrix} 1& 1\\ 1& 0 \end{bmatrix},n-1),就可以得到\begin{bmatrix} Fn &Fn-1 \end{bmatrix}


算法过程

pow函数可以使用quick_pow快速实现。

我们还需要重载*运算符来实现矩阵乘法。

使用三重for循环枚举A的i行,B的j列以及A[i][k]*B[k][j] 。

using row = vector<long long>;
using matrix = vector<row>;
matrix operator *(const matrix& A, const matrix& B) {matrix ans(A.size(), row(B[0].size()));for (int i = 0; i < A.size(); i++)for (int j = 0; j < B[0].size(); j++)for (int k = 0; k < A[0].size(); k++)ans[i][j] = (ans[i][j] + A[i][k] * B[k][j]);return ans;
}

正如普通的quick_pow初始化ans为1,我们将矩阵快速幂的ans初始化为\begin{bmatrix} 1&0 \\ 0&1 \end{bmatrix} ,即单位矩阵,它的定位等同于1,任何矩阵乘以单位矩阵都等于原矩阵。

matrix quick_pow(matrix x, int n) {matrix ans={{1,0},{0,1}};while (n) {if (n & 1)ans = ans * x;x = x * x;n >>= 1;}return ans;
}

复杂度

时间复杂度: O(logn)

空间复杂度: O(1)


Code

long long quick_pow(long long x, int n) {long long ans = 1;while (n) {if (n & 1)ans *= x;x *= x;n >>= 1;}return ans;
}
using row = vector<long long>;
using matrix = vector<row>;
matrix operator *(const matrix& A, const matrix& B) {matrix ans(A.size(), row(B[0].size()));for (int i = 0; i < A.size(); i++)for (int j = 0; j < B[0].size(); j++)for (int k = 0; k < A[0].size(); k++)ans[i][j] = (ans[i][j] + A[i][k] * B[k][j]);return ans;
}
matrix quick_pow(matrix x, int n) {matrix ans={{1,0},{0,1}};while (n) {if (n & 1)ans = ans * x;x = x * x;n >>= 1;}return ans;
}
class Solution {
public:int fib(int n) {if (!n)return 0;matrix m = { {1,0} }, coefficient = { {1,1},{1,0} };matrix c = quick_pow(coefficient, n - 1);matrix ans = m * c;return ans[0][0];}
};

 

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

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

相关文章

linux--库指令

ldd ldd 可执行文件路径 显示依赖的库的查找路径以及是否查找到了。

思迅商云8修改最大找零金额

执行如下语句前请备份数据库 -POS收银找零金额最大数 --把下面SQL中的 1000.00 改成你想要的金额数&#xff0c;再到查询分析器中执行&#xff1a; --总店 use hbposv8 go insert t_sys_system (sys_var_id, sys_var_value, sys_var_name) values (pos_max_givchg, 1000.00, 最…

zookeeper问题

启动zk的时候&#xff0c;发现zk起来就秒挂 2024-10-11 15:12:58,532 [myid:1]- ERROR [main:QuorumPeer692] - Unable to load database on disk java.io.I0Exception: The current epoch, 6, is older than the last zxid, 30064771079 at org.apache.zookeeper.server.quoru…

Java基础系列-一文搞懂自定义排序

java自定义排序 自定义排序的理解&#xff1a; 我们首先看需求&#xff1a;一个二维数组 [[1,3],[8,10],[15,18],[2,6]] 我们的需求是根据集合&#xff08;二维数组取出来的数据&#xff09; 左边小的左边这种方式排序 例如1<8 排序方式就是[1,3],[8,10] 此时我们就需…

Dockerfile 中,把多个 RUN 合并在一起,能减少镜像尺寸吗?

先说结论&#xff1a; 有些时候能&#xff0c;有些时候不能&#xff0c;但你要明白原理 – Docker 使用 UnionFS&#xff0c;镜像尺寸随着层数增多&#xff0c;是单调非减的。 问题 看到一个 Dockerfile&#xff1a; FROM python:3.17.7-alpine3.20 RUN pip3 install pillow…

Unity3D 同步怪物实体到客户端详解

在游戏开发中&#xff0c;经常会遇到需要同步怪物实体到客户端的需求。本文将详细介绍如何在Unity3D中实现怪物实体的同步&#xff0c;并给出技术详解以及代码实现。 对惹&#xff0c;这里有一个游戏开发交流小组&#xff0c;大家可以点击进来一起交流一下开发经验呀&#xff…

Request2:Post请求和Json

百度翻译拿到自己想看的数据&#xff0c;下图查看请求到数据的请求 preview提前看下 取出对应的RequestUrl &#xff0c;看出来要使用的话得用post请求 #!/usr/bin/env python # -*- coding:utf-8 -*- import requests import json if __name__ "__main__":#1.指定…

SAP物料凭证报表字段调整

业务场景&#xff1a; 报表MB51的输入和输出字段调整&#xff1a; 输入&#xff08;选择界面&#xff09; 输出界面 可以看到在这是没有布局调整的 后台路径&#xff1a; SPRO-物料管理-库存管理和实际库存-报表-定义物料凭证列表的字段选择 事务码&#xff1a;SM30-V_MMI…

【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,1-10

文件下载与邀请翻译者 学习英特尔开发手册&#xff0c;最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册&#xff0c;会是一件耗时费力的工作。如果有愿意和我一起来做这件事的&#xff0c;那么&#xff…

FPGA学习(6)-基础语法参数化设计阻塞与非阻塞

目录 1.两种参数化不改变源文件&#xff0c;只改仿真文件的值 2.参数化设计实现模块的重用 2.1不用参数化方法 2.1.1源文件 2.1.2仿真文件 2.1.3仿真波形及实验 2.2 用参数方法 2.2.1调用之前写的led灯闪烁模块&#xff0c;在本源函数中&#xff0c;例化4次调用之前的模…

ip a查看网卡接口信息

ip a命令是用于查看和管理网络接口信息的命令。通过执行ip a命令&#xff0c;可以查看当前系统上所有网络接口的配置信息&#xff0c;包括IP地址、子网掩码、网关、MAC地址等。该命令还可以用于配置网络接口的参数&#xff0c;如设置IP地址、启用或禁用接口等操作。 # ip a 1:…

史上最烂 spring transaction 原理分析

史上最烂 spring transaction 原理分析 事务定义、事务作用、事务特性、生命周期、数据库事务三种运行模式、数据库事务控制、并发事务问题、隔离级别、数据库事务实现原理、spring 事务传播行为、spring 事务核心组件、spring boot 事务相关组件、事务嵌套原理、编程式事务与声…

51单片机的万年历【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块时钟模块按键蜂鸣器等模块构成。适用于电子万年历、数字时钟万年历等相似项目。 可实现功能: 1、LCD1602实时显示年月日星期和北京时间&#xff0c;具备闰年判断功能 2、按键可设置闹钟时间 3、按键可修改当前时…

MAL-PEG-SVA MW2000 丙烯酰氯基 共轭反应 靶向传递 共价结合

MAL-PEG-SVA是一种带有丙烯酰氯基和马来酰亚胺的聚乙二醇衍生物。它具有良好的溶解性、生物相容性和化学稳定性&#xff0c;因此在许多领域都有广泛的应用。 以下是MAL-PEG-SVA的一些主要应用和相应的例子&#xff1a; 1. 蛋白质修饰&#xff1a;MAL-PEG-SVA可用于蛋白质的修饰…

CVTE Android面试题及参考答案(100道题)

目录 插件化 组件化 合并相似接口 抽象通用方法 使用接口代理 引入设计模式 编写源代码 资源文件准备 编译资源文件 编译源代码 生成 dex 文件 打包 APK 文件 技术能力提升 项目经验积累 职业发展 知识分享与团队协作 建立良好的沟通机制 明确团队目标和职责…

深度学习代码学习笔记2

1、torch.max correct 0 total 0 for xb,yb in valid_dl:outputs model(xb)_,predicted torch.max(outputs.data,1)total yb.size(0) #yb.size(0) 返回的是张量 yb 在第 0 维的大小&#xff0c;也就是 yb 中的样本数量。correct (predicted yb).sum().item() print(…

[Halcon矩阵] 通过手眼标定矩阵计算相机旋转角度

&#x1f4e2;博客主页&#xff1a;https://loewen.blog.csdn.net&#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;本文由 丶布布原创&#xff0c;首发于 CSDN&#xff0c;转载注明出处&#x1f649;&#x1f4e2;现…

C++服务端的配置文件库介绍

文章目录 1. inih 库原理使用方法 2. Boost.PropertyTree 库原理使用方法 3. jsoncpp 库原理使用方法 在 C 项目中&#xff0c;灵活地读取用户配置是提升软件可用性的重要部分。本文将介绍几种常见的 C 配置库&#xff0c;包括它们的原理和使用方法。 1. inih 库 原理 inih …

桥接模式、NAT模式 和 主机模式(Host-Only)区别

在虚拟化和网络配置中&#xff0c;桥接模式、NAT模式 和 主机模式&#xff08;Host-Only&#xff09;是虚拟机常用的网络连接模式。它们各自的网络特性和使用场景不同。下面详细分析它们的区别和适用场景。 1. 桥接模式 (Bridged Mode) 原理&#xff1a; 虚拟机的网卡会直接与…

06.队列介绍+实现

目录 一、队列的概念 二、队列的实现 1、头文件定义 2、功能函数实现 3、主函数测试 一、队列的概念 队列就像吃饭排队类似&#xff0c;先来先吃&#xff0c;先进先出。 队头&#xff1a;队列的头部。 队尾&#xff1a;队列的尾部。 入队&#xff1a;在队尾操作。 出队&…