1137 第N个泰波那契数 力扣 动态规划 快速幂

本文介绍了如何使用动态规划和矩阵快速幂的方法求解泰波那契数列问题,通过矩阵乘法和幂运算简化计算过程,同时讨论了数据类型选择以避免溢出问题。
摘要由CSDN通过智能技术生成

1137 第N个泰波那契数 力扣 动态规划 快速幂

  • 动态规划 递推练习
  • 尝试了一下昨天的思路,练习利用矩阵幂来解决这种问题
  • 本来首先尝试的官方题解那样解法的,但是不知道一开始做的时候觉得怪怪的,就换了这个思路,其实大差不差
  • 关键在于找到进行幂乘的初始矩阵,以及确定指数是否为n(因为本题的状态选取影响了指数并不是n)
  • 最后判断是选取得到的矩阵的哪一个元素
  • 还要注意的一点是,矩阵里单个元素类型,因为是幂次所以如果定义为int,n稍大就很容易溢出,所以可定义为long ,或者long long
  • 就本题而言AC比较容易,也没有那么复杂,只不过就是借本题来练习一下这个思路

分析:

在这里插入图片描述

本人代码

class Solution {
public:
    vector<vector<long>>multiply(vector<vector<long>>& a, vector<vector<long>>& b)
 {
     vector<vector<long>>c(3,vector<long> (3));
     for (int i = 0; i < 3; i++)
         for (int j = 0; j < 3; j++)
             c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
     //矩阵乘法 3*3
     return c;
 };
 vector<vector<long>>matrix_pow(vector<vector<long>>a, int n)
 {
     //快速幂
     vector<vector<long>> ret = { {1,0,0},{0,1,0},{0,0,1} };
     while (n>0)
     {
         if ((n & 1) == 1)ret = multiply(ret, a);//单位矩阵乘以初始矩阵
         n >>= 1; //n/2;
         a = multiply(a, a);
     }
     return ret;
 };
 int tribonacci(int n) {
     //矩阵角度 
     vector<vector<long>> initial_A = { {4,3,2},{2,2,1},{1,1,1}};
     /*系数矩阵: [4 3 2
     			  2 2 1      考虑到矩阵乘法实现函数里是3*3的方阵相乘,
     			  1 1 1]      所以把初始矩阵阔成了了3*3 
     */
     /*  初始矩阵:[1 0 0
     			   1 0 0	第一列对应 T2,T1,T0取值 1, 1, 0,第二三列无关补
     			   0 0 0]		充0,主要是为了同型
     */
      vector<vector<long>> initial_B = {{1,0,0},{1,0,0},{0,0,0}};
     int t_0 = 0, t_1 = 1, t_2 = 1;
     if (n == 0)return 0;
     if ((n == 1)||(n == 2))return 1;
     vector<vector<long>> f = matrix_pow(initial_A,(n/3));
     vector<vector<long>> res=multiply(f,initial_B);
    if(n%3== 0) return res[2][0];   
    else if(n%3==1) return res[1][0];
    else return res[0][0];  //因为结果矩阵第一列对应的就是T(n+2),T(n+1),T(n),此处n只能为3的倍数,所以n=3k时就是第三行第一个,n=3k+1时就是第二行第一个,n=3k+2时就对应第一行第一个,
 }
};
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值