zoukankan      html  css  js  c++  java
  • 爬楼梯

    1.题目描述

    假设你正在爬楼梯。需要n阶你才能到达楼顶。
    每次你可以爬12个台阶。你有多少种不同的方法可以爬到楼顶呢?
    注意:给定n是一个正整数。
    示例 1:

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

    示例 2:

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

    2.题解

    2.1 矩阵快速幂

    public int climbStairs(int n) {
    	int[][] q = {{1, 1}, {1, 0}};
    	int[][] res = pow(q, n);
    	return res[0][0];
    }
    
    public int[][] pow(int[][] a, int n) {
    	int[][] ret = {{1, 0}, {0, 1}};
    	while (n > 0) {
    		if ((n & 1) == 1) {
    			ret = multiply(ret, a);
    		}
    		n >>= 1;
    		a = multiply(a, a);
    	}
    	return ret;
    }
    
    public int[][] multiply(int[][] a, int[][] b) {
    	int[][] c = new int[2][2];
    	for (int i = 0; i < 2; i++) {
    		for (int j = 0; j < 2; j++) {
    			c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j];
    		}
    	}
    	return c;
    }
    

    快速幂(Exponentiation by squaring,平方求幂)是快速计算一个数的大正整数幂的一般方法。
    相关阅读:

    矩阵快速幂指的是底数为矩阵的快速幂。那么矩阵是什么?矩阵是为了解决什么问题?
    相关阅读:

    由递推关系得:

    [egin{bmatrix} f(n+1)\ f(n) end{bmatrix}= egin{bmatrix} 1 & 1\ 1 & 0 end{bmatrix} ^{n} egin{bmatrix} f(1)\ f(0) end{bmatrix} ]

    n = 5时,

    [egin{bmatrix} f(6)\ f(5) end{bmatrix}= egin{bmatrix} 8 & 5\ 5 & 3 end{bmatrix} egin{bmatrix} f(1)\ f(0) end{bmatrix} ]

    最终结果取res[0][0],于是,这里(f(5)=8),但这是为什么呢?
    注意到(f(0)=1)(f(1)=1),所以(f(6)=8+5)(f(5)=5+3)
    这里的矩阵第一行第一列的元素8为什么刚好等于第二行元素的和(5+3)?

    n=1时,(egin{bmatrix} 1 & 1 \ 1 & 0 end{bmatrix}^{1}=egin{bmatrix} 1 & 1 \ 1 & 0 end{bmatrix})
    n=2时,(egin{bmatrix} 1 & 1 \ 1 & 0 end{bmatrix}^{2}=egin{bmatrix} 2 & 1 \ 1 & 1 end{bmatrix})
    n=3时,(egin{bmatrix} 1 & 1 \ 1 & 0 end{bmatrix}^{3}=egin{bmatrix} 3 & 2 \ 2 & 1 end{bmatrix})
    n=4时,(egin{bmatrix} 1 & 1 \ 1 & 0 end{bmatrix}^{4}=egin{bmatrix} 5 & 3 \ 3 & 2 end{bmatrix})
    n=5时,(egin{bmatrix} 1 & 1 \ 1 & 0 end{bmatrix}^{5}=egin{bmatrix} 8 & 5 \ 5 & 3 end{bmatrix})

    假设(egin{bmatrix} a & b \ c & d end{bmatrix}=egin{bmatrix} 1 & 1 \ 1 & 0 end{bmatrix}),于是有:

    (egin{bmatrix} a & b \ c & d end{bmatrix}egin{bmatrix} a & b \ c & d end{bmatrix}=egin{bmatrix} a+b & a \ c+d & c end{bmatrix})

    (egin{bmatrix} a & b \ c & d end{bmatrix}egin{bmatrix} a & b \ c & d end{bmatrix}egin{bmatrix} a & b \ c & d end{bmatrix}=egin{bmatrix} a+b & a \ c+d & c end{bmatrix}egin{bmatrix} a & b \ c & d end{bmatrix}=egin{bmatrix} 2a+b & a+b \ 2c+d & c+d end{bmatrix})

    这里很好地解释了当n=5时,为什么矩阵第一行第一列的元素8为什么刚好等于第二行元素的和(5+3)。
    因为矩阵第一行第一列的元素值为上一个矩阵的第一行元素的和,但为什么矩阵第二行元素刚好是上一个矩阵的第一行元素呢?
    矩阵第二行第一列的元素值为上一个矩阵的第二行元素的和,而矩阵第二行第二列的元素为上一个矩阵的第二行第一列的元素。
    结合第一个矩阵为(egin{bmatrix} 1 & 1 \ 1 & 0 end{bmatrix}),所以矩阵第二行元素刚好是上一个矩阵的第一行元素。

    参考:

  • 相关阅读:
    应用服务器安装
    datasnap的线程池
    压缩OLEVARIANT数据
    服务端日志记录
    提交主从表的多个已经修改的数据
    MySQL与PostgreSQL相比哪个更好?
    Vue入门常用指令详解
    Laravel模型事件的实现原理详解
    Git 遇到了 early EOF indexpack failed 问题
    Laravel 代码开发最佳实践
  • 原文地址:https://www.cnblogs.com/gzhjj/p/14250118.html
Copyright © 2011-2022 走看看