二项式定理(Binomial Theorem)就是: ( x + y ) n (x + y)^n (x+y)n 的展开:
( x + y ) n = C n 0 a n b 0 + C n 1 a ( n − 1 ) b 1 + . . . + C n n − 1 a 1 b n − 1 + C n n a 0 b n (x + y)^n = C_n^0 a^n b^0 + C_n^1 a^{(n-1)} b^1 + ... + C_n^{n - 1} a^1 b^{n - 1} + C_n^n a^0 b^n (x+y)n=Cn0anb0+Cn1a(n−1)b1+...+Cnn−1a1bn−1+Cnna0bn
比如最简单的:
(
x
+
y
)
2
=
a
2
+
2
a
b
+
b
2
(x + y)^2 = a^2 + 2ab + b^2
(x+y)2=a2+2ab+b2,也就是输入 2
,输出 1 2 1
;
再比如:
(
x
+
y
)
3
=
a
3
+
3
a
2
b
+
3
a
b
2
+
b
3
(x + y)^3 = a^3 + 3a^2b + 3ab^2 + b^3
(x+y)3=a3+3a2b+3ab2+b3,也就是输入 3
,输出 1 3 3 1
。
其实就是 n 次方会有 n + 1 项,系数从
C
n
0
C_n^0
Cn0 到
C
n
n
C_n^n
Cnn。
在计算每一项的时候,不能直接按照
n
!
m
!
⋅
(
n
−
m
)
!
\frac {n!}{m! \cdot(n - m)!}
m!⋅(n−m)!n! 来计算,因为算分子的时候 long long 都会溢出,计算方式是分子从 n - m + 1
算到 n
,分母从 1
算到 m
,这样相当于把
(
n
−
m
)
!
(n - m)!
(n−m)! 除掉了,每次乘一个,除一个,有证明可以证明不会出现整除不了的情况,这样再用 long long 就不会溢出了。
#include <iostream>
#include <vector>
using namespace std;
long long combinations(int m, int n) {
long long res = 1; // 必须是long long
for (int i = 1; i <= m; ++i) {
res *= (n - m + i);
res /= i;
}
return res;
}
int main() {
int n;
cin >> n;
for (int i = 0; i < n; ++i)
cout << combinations(i, n) << ' ';
cout << 1 << endl;
}
因为 C n m = C n n − m C_n^m = C_{n}^{n-m} Cnm=Cnn−m,所以其实还可以优化。