动态规划与矩阵对角化

动态规划与矩阵对角化

题目描述:

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

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

链接:https://leetcode-cn.com/problems/climbing-stairs/

本文重点给出递推方程对角化的求解

易知求n阶楼梯走法,有两种选择,其递推方程为

f ( n ) = f ( n − 1 ) + f ( n − 2 ) f(n) = f(n - 1) + f(n - 2) f(n)=f(n1)+f(n2)
建立方程组:
f ( n ) = f ( n − 1 ) + f ( n − 2 ) f ( n − 1 ) = f ( n − 1 ) \begin{aligned} f(n) & = f(n - 1) + f(n - 2) \\ f(n - 1) & = f(n - 1) \\ \end{aligned} f(n)f(n1)=f(n1)+f(n2)=f(n1)
其矩阵形式为:

[ 1 1 1 0 ] [ f ( n − 1 ) f ( n − 2 ) ] = [ f ( n ) f ( n − 1 ) ] \left[ {\begin{array}{ccccccccccccccc}1&1\\1&0\end{array}} \right]\left[ {\begin{array}{ccccccccccccccc}{f(n - 1)}\\{f(n - 2)}\end{array}} \right] = \left[ {\begin{array}{ccccccccccccccc}{f(n)}\\{f(n - 1)}\end{array}} \right] [1110][f(n1)f(n2)]=[f(n)f(n1)]

根据递推我们可以得到
[ 1 1 1 0 ] n − 1 [ f ( 2 ) f ( 1 ) ] = [ f ( n ) f ( n − 1 ) ] {\left[ {\begin{array}{ccccccccccccccc}1&1\\1&0\end{array}} \right]^{n - 1}}\left[ {\begin{array}{ccccccccccccccc}{f(2)}\\{f(1)}\end{array}} \right] = \left[ {\begin{array}{ccccccccccccccc}{f(n)}\\{f(n - 1)}\end{array}} \right] [1110]n1[f(2)f(1)]=[f(n)f(n1)]
对于计算矩阵的n次幂,如果矩阵可以对角化,可以使用对角化简化计算。

对角化过程

通过 ( A − λ E ) x = 0 (A - \lambda E)x = 0 (AλE)x=0,我们可以得到其两个特征值为 1 + 5 2 \frac{{1 + \sqrt 5 }}{2} 21+5 1 − 5 2 \frac{{1 - \sqrt 5 }}{2} 215 ,相应的特征向量分别为
[ 1 + 5 2 1 ] 和 [ 1 − 5 2 1 ] \left[ {\begin{array}{ccccccccccccccc}{\frac{{1 + \sqrt 5 }}{2}}\\1\end{array}} \right]和\left[ {\begin{array}{ccccccccccccccc}{\frac{{1 - \sqrt 5 }}{2}}\\1\end{array}} \right] [21+5 1][215 1]
同时求得特征向量矩阵的逆矩阵为
1 5 [ 1 − 1 5 − 1 2 5 + 1 2 ] \frac{1}{{\sqrt 5 }}\left[ {\begin{array}{ccccccccccccccc}1&{ - 1}\\{\frac{{\sqrt 5 - 1}}{2}}&{\frac{{\sqrt 5 + 1}}{2}}\end{array}} \right] 5 1[125 1125 +1]
所以
[ 1 1 1 0 ] n − 1 = 1 5 [ 1 + 5 2 1 − 5 2 1 1 ] [ ( 1 + 5 2 ) n − 1 0 0 ( 1 − 5 2 ) n − 1 ] [ 1 − 1 5 − 1 2 5 + 1 2 ] {\left[ {\begin{array}{ccccccccccccccc}1&1\\1&0\end{array}} \right]^{n - 1}} = \frac{1}{{\sqrt 5 }}\left[ {\begin{array}{ccccccccccccccc}{\frac{{1 + \sqrt 5 }}{2}}&{\frac{{1 - \sqrt 5 }}{2}}\\1&1\end{array}} \right]\left[ {\begin{array}{ccccccccccccccc}{{{(\frac{{1 + \sqrt 5 }}{2})}^{n - 1}}}&0\\0&{{{(\frac{{1 - \sqrt 5 }}{2})}^{n - 1}}}\end{array}} \right]\left[ {\begin{array}{ccccccccccccccc}1&{ - 1}\\{\frac{{\sqrt 5 - 1}}{2}}&{\frac{{\sqrt 5 + 1}}{2}}\end{array}} \right] [1110]n1=5 1[21+5 1215 1][(21+5 )n100(215 )n1][125 1125 +1]
源码如下:

class Solution {
    public int climbStairs(int n) {
        double sqrt5=Math.sqrt(5);
        double[][] eigenMatrix={{(sqrt5+1)/2,(1-sqrt5)/2},{1,1}};
        double[][] eigenMatrixInv={{1,(sqrt5-1)/2},{-1,(sqrt5+1)/2}};//特征向量矩阵的逆/sqrt5
        double[][] lambda={{Math.pow((sqrt5+1)/2,n-1),0},{0,Math.pow((1-sqrt5)/2,n-1)}};//特征值对角矩阵
        double[][] muliply=matrixMultiply(matrixMultiply(eigenMatrix,lambda),eigenMatrixInv);
        double result=(2*muliply[1][0]+1*muliply[1][1])/sqrt5;
        return (int)Math.round(result);
    }
    public double[][] matrixMultiply(double[][] a,double[][] b){
        double[][] result=new double[a.length][b[0].length];
        double[] colOfB=new double[b[0].length];
        for(int i=0;i<a.length;i++){
            for(int j=0;j<b[0].length;j++){
                for(int k=0;k<b.length;k++)
                    colOfB[k]=b[k][j];
                result[i][j]=vectorMultiply(a[i],colOfB);
            }
        }
        return result;
    }
    public double vectorMultiply(double[] a,double[] b){
        double result=0.0;
        for(int i=0;i<a.length;i++){
            result+=a[i]*b[i];
        }
        return result;
    }
    
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值