当前位置: 首页 > news >正文

[矩阵快速幂] 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶

示例 2:

输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

解题分析

爬楼梯的话其实蛮明显的一个递推关系,dp[i]=dp[i-1]+dp[i-2]; 不过这样的话其实很容易发现一个问题,一旦数据过大就会导致C++ 原本的int或者long long 超类型。然后时间复杂度也达到了O(n)。那么有没有什么更快的方法可以快一些得到答案呢。我们观察这个递推公式,很容易想到一个矩阵。矩阵的特点是第一行都是dp[i-1]和dp[i-2]前面的系数,也就是{1,1}。矩阵的左下角的降阶矩阵是一个单位矩阵,也就是对角线上都是1。对于二阶矩阵而言,就是{{1,1},{1,0}},用这个矩阵乘上矩阵{{f(n)},{f(n-1)}}。可以得到矩阵{{f(n+1)},{f(n)}}。也就是说,我们不断递推的话可以得到一个很好看的公式{{f(n+1)},{f(n)}}=({{1,1},{1,0}})^n*{{f(1)},{f(0)}}。所以说,我们只需要去求出一个矩阵的n次幂,然后利用这个递推公式很快就能求出f(n)了。但是呢,如果我们之间去求矩阵的次幂,那也会导致时间复杂度过高。有没有什么办法?当然有,那就是矩阵快速幂。我们可以想,如果我们要求一个矩阵A的10次方,我们先把10转换为二进制1010,现在,我们可以进入一个循环,判断条件是n=1010(2)大于0。我们每次进入循环判断n的最后一位是不是1,如果是,我们就用ret(初始化为一个单位矩阵)乘上A;如果不是,我们啥也不做。然后我们令n>>=1; 之后我们让A*=A。也就是自己倍乘一下。这样,循环结束后我们得到的矩阵ret就是A的n次方啦,而且很明显时间的复杂度为O(logn),相比较原来的时间复杂度可以说有巨大的提升。最后,我们根据矩阵乘法的关系直接输出答案即可。

代码实现

class Solution {
public:vector<vector<long long>> multiply(vector<vector<long long>>& a,vector<vector<long long>>& b,int n=2){vector<vector<long long>> c(n,vector<long long>(n));for(int i=0;i<n;i++){for(int j=0;j<n;j++){c[i][j]=0;for(int k=0;k<n;k++){c[i][j]+=a[i][k]*b[k][j];}}}return c;}vector<vector<long long>> matrixPow(vector<vector<long long>> a, int n) {vector<vector<long long>> ret = {{1, 0}, {0, 1}};while (n > 0) {if ((n & 1) == 1) {ret = multiply(ret, a);}n >>= 1;a = multiply(a, a);}return ret;}int climbStairs(int n) {vector<vector<long long>> ret = {{1, 1}, {1, 0}};vector<vector<long long>> res = matrixPow(ret, n);return res[1][0]+res[1][1];}
};


http://www.mrgr.cn/news/17982.html

相关文章:

  • 论文解读汇总(目标检测、目标跟踪、语义分割....)定期更新
  • 将传统ViT用于分割或检测任务
  • 中资优配:什么股票容易涨停?放量涨停意味着什么?
  • Transformer简明笔记:文本翻译
  • 绿色物流:TMS在节能减排中的角色
  • 深入理解MySQL慢查询优化(1) -- 优化策略
  • Maven的常用插件
  • 台球助教预约系统小程序源码开发
  • 字符分类函数
  • 2024.08.26 校招 实习 内推 面经
  • 公司企业大楼智慧厕所建设步骤和技术要求@卓振思众
  • 在线演示文稿应用PPTist本地化部署并实现无公网IP远程编辑PPT
  • 考试系统将来市场会如何
  • centos7使用ifconfig查看IP,终端无ens33信息解决办法
  • Java基于微信小程序的超市购物管理系统
  • 多重背包问题 模板 C++实现
  • 关于contextmenu-ui组件库
  • 【Python123题库】#统计文章字符数 #查询高校信息 #查询高校名
  • IM项目:进阶版即时通讯项目---项目总览
  • Trino大量查询会导致HDFS namenode主备频繁切换吗?