题目描述
组合数 C(n,m)是从 n 个物品中取 m 个的方案数。
\(\displaystyle C(n,m) = \frac {n!}{m!(n-m)!}\)
斐波那契数列 F 满足,\(F[0]=F[1]=1,n≥2 时 F[n]=F[n-1]+F[n-2]\)
给出 n,求 \(C(n,0)F[0]+C(n,1)F[1]+...+C(n,n)F[n]\)
solution
题目也就是让你求这么一个东西:
\(\displaystyle \sum_{i = 0}^{n} {n\choose i}f[i]\)
由斐波那契数列的通项公式:
\(\displaystyle f[n] = \frac{1}{\sqrt 5}((\frac {1 + \sqrt 5}{2}) ^n -(\frac {1 - \sqrt 5}{2}) ^n)\)
然后上边的式子就变成了
\(\displaystyle \sum_{i = 0}^{n} {n\choose i} \frac{1}{\sqrt 5}((\frac {1 + \sqrt 5}{2}) ^i -(\frac {1 - \sqrt 5}{2}) ^i)\)
\(= \frac{1}{\sqrt 5} \displaystyle \sum_{i = 0}^{n} {n\choose i} ((\frac {1 + \sqrt 5}{2}) ^i -(\frac {1 - \sqrt 5}{2}) ^i)\)
\(= \frac{1}{\sqrt 5}( \displaystyle \sum_{i = 0}^{n} {n\choose i} (\frac {1 + \sqrt 5}{2}) ^i - \sum_{i = 0}^{n} {n\choose i}(\frac {1 - \sqrt 5}{2}) ^i) \ \ \ \ \ ①\)
由二项式定理(二项式定理暴拆证明):
\((a + b) ^n = \displaystyle \sum _{k = 0}^{n} {n \choose k} a^{n - k}b^k\)
令\(a == 1\) 原式:
\((1 + b) ^n = \displaystyle \sum _{k = 0}^{n} {n \choose k} b^k\)
然后我们回头看①,把上边式子带入可得:
\(=\displaystyle \frac{1}{\sqrt 5}((1 + \frac {1 + \sqrt 5}{2}) ^n - (1+\frac {1 - \sqrt 5}{2}) ^n)\)
$=\displaystyle \frac{1}{\sqrt 5}((\frac {3 + \sqrt 5}{2})^n - (\frac {3 - \sqrt 5}{2}) ^n) $
\(=\displaystyle \frac{1}{\sqrt 5}((\frac {6 + 2\sqrt 5}{4})^n - (\frac {6 - 2\sqrt 5}{4}) ^n)\)
\(=\displaystyle \frac{1}{\sqrt 5}((\frac {1 + 2\sqrt 5 + 5}{4}) ^n - (\frac {1 - 2\sqrt 5+5}{4}) ^n)\)
\(=\displaystyle \frac{1}{\sqrt 5}(((\frac {1 + \sqrt 5}{2})^2) ^n - ((\frac {1 - \sqrt 5}{2})^2) ^n)\)
\(=\displaystyle \frac{1}{\sqrt 5}((\frac {1 + \sqrt 5}{2})^{2n} - (\frac {1 - \sqrt 5}{2})^{2n})\)
孩子回头看看上边斐波那契数列的通项公式吧,有惊喜呦
没错,最后的答案就是斐波那契数列的第2n项
code
/*
Auther:_Destiny
time:2020 4 28
*/
#include <bits/stdc++.h>
#define ll long long
#define N 2000010
#define M 1010
using namespace std;
const int mod = 1e9 + 7;
ll f[N];
ll read() {
ll s = 0, f = 0; char ch = getchar();
while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
return f ? -s : s;
}
int main() {
f[0] = f[1] = 1;
for (int i = 2; i <= 2000000; ++i)
f[i] = (f[i - 1] + f[i - 2]) % mod;
int T = read();
while (T--) {
int n = read();
printf("%lld\n", f[2 * n]);
}
}