预备
矩阵幂运算
比如计算矩阵a的4次方,是通过
b
=
a
∗
a
,
c
=
b
∗
b
b = a * a,c = b * b
b=a∗a,c=b∗b 得到的答案c,计算了n/2次。
https://leetcode-cn.com/problems/climbing-stairs/
f
[
n
]
=
f
[
n
−
1
]
+
f
[
n
−
2
]
=
f
[
n
−
2
]
+
f
[
n
−
3
]
+
f
[
n
−
3
]
+
f
[
n
−
4
]
=
f
[
n
−
3
]
+
f
[
n
−
4
]
+
f
[
n
−
4
]
+
f
[
n
−
5
]
+
f
[
n
−
5
]
+
f
[
n
−
6
]
+
f
[
n
−
6
]
+
f
[
n
−
7
]
=
.
.
.
=
a
∗
f
[
0
]
+
b
∗
f
[
1
]
\begin{aligned} f[n] &= f[n-1] + f[n-2] \\ & = f[n-2] + f[n-3] + f[n-3] + f[n-4]\\ & = f[n-3] + f[n-4] + f[n-4] + f[n-5] + f[n-5] + f[n-6] + f[n-6] + f[n-7]\\ & = ...\\ &= a * f[0] + b * f[1] \end{aligned}
f[n]=f[n−1]+f[n−2]=f[n−2]+f[n−3]+f[n−3]+f[n−4]=f[n−3]+f[n−4]+f[n−4]+f[n−5]+f[n−5]+f[n−6]+f[n−6]+f[n−7]=...=a∗f[0]+b∗f[1]
进而转化为求a,b的值
反推可得:
f
[
1
]
=
f
[
1
]
+
0....
=
1
∗
f
[
1
]
+
0
∗
f
[
0
]
f
[
2
]
=
f
[
1
]
+
f
[
0
]
=
1
∗
f
[
1
]
+
1
∗
f
[
0
]
f
[
3
]
=
f
[
2
]
+
f
[
1
]
=
2
∗
f
[
1
]
+
1
∗
f
[
0
]
f
[
4
]
=
f
[
3
]
+
f
[
2
]
=
3
∗
f
[
1
]
+
2
∗
f
[
0
]
f
[
5
]
=
f
[
4
]
+
f
[
3
]
=
5
∗
f
[
1
]
+
3
∗
f
[
0
]
f
[
n
]
=
f
[
n
−
1
]
+
f
[
n
−
2
]
=
a
∗
f
[
0
]
+
b
∗
f
[
1
]
f[1] = f[1] + 0.... = 1 * f[1] + 0 * f[0] \\ f[2] = f[1] + f[0] = 1 * f[1] + 1 * f[0] \\ f[3] = f[2] + f[1] = 2 * f[1] + 1 * f[0] \\ f[4] = f[3] + f[2] = 3 * f[1] + 2 * f[0] \\ f[5] = f[4] + f[3] = 5 * f[1] + 3 * f[0] \\ f[n] = f[n-1] + f[n-2] = a * f[0] + b * f[1]
f[1]=f[1]+0....=1∗f[1]+0∗f[0]f[2]=f[1]+f[0]=1∗f[1]+1∗f[0]f[3]=f[2]+f[1]=2∗f[1]+1∗f[0]f[4]=f[3]+f[2]=3∗f[1]+2∗f[0]f[5]=f[4]+f[3]=5∗f[1]+3∗f[0]f[n]=f[n−1]+f[n−2]=a∗f[0]+b∗f[1]
观察可得,系数a,b也是累加得出的。
[
f
[
0
]
f
[
1
]
]
\begin{bmatrix} f[0]&f[1] \\ \end{bmatrix}
[f[0]f[1]] *
[
0
1
1
1
]
n
−
1
\begin{bmatrix} 0 & 1 \\ 1 & 1 \\ \end{bmatrix}^{n-1}
[0111]n−1 =
[
f
[
n
−
1
]
f
[
n
]
]
\begin{bmatrix} f[n-1]&f[n] \\ \end{bmatrix}
[f[n−1]f[n]]
class Solution {
public:
int matrix(int n){
int a[2][2] = {{0,1},{1,1}};
int b[2][2] = {{0,1},{1,1}};
int c[2][2] = {{0,1},{1,1}};
int d[2][2] = {{0,1},{1,1}};
int flag = 0;
if(n % 2)
flag = 1;
n /= 2;
while(n > 1){
c[0][0] = b[0][0]*a[0][0]+b[0][1]*a[1][0];
c[0][1] = b[0][0]*a[0][1]+b[0][1]*a[1][1];
c[1][0] = b[1][0]*a[0][0]+b[1][1]*a[1][0];
c[1][1] = b[1][0]*a[0][1]+b[1][1]*a[1][1];
for(int i = 0;i < 2;i++)
for(int j = 0;j < 2;j++)
b[i][j] = c[i][j];
n--;
}
d[0][0] = c[0][0]*c[0][0]+c[0][1]*c[1][0];
d[0][1] = c[0][0]*c[0][1]+c[0][1]*c[1][1];
d[1][0] = c[1][0]*c[0][0]+c[1][1]*c[1][0];
d[1][1] = c[1][0]*c[0][1]+c[1][1]*c[1][1];
if(flag == 0){
return d[1][0] + d[1][1] * 2;
}
else{
c[1][0] = d[1][0]*a[0][0]+d[1][1]*a[1][0];
c[1][1] = d[1][0]*a[0][1]+d[1][1]*a[1][1];
return c[1][0] + c[1][1] * 2;
}
}
int climbStairs(int n) {
if(n == 1 || n == 2 || n == 3)
return n;
n -= 2;
return matrix(n);
}
};