复杂度:O(n^2)
C[i][j]即为C(i,j);
#include <bits/stdc++.h> using namespace std; const int MOD = 1e9+7; const int maxn = 1e3; typedef long long ll; int n,k; ll C[maxn][maxn]; int main() { n = 100; memset(C,0,sizeof(C)); for(int i = 0; i <= n; i++) { C[i][0] = 1; for(int j = 1; j<=i; j++) C[i][j] = C[i-1][j-1] + C[i-1][j]; } printf("%lld\n",C[4][2]); return 0; }
利用递推公式:C(n,k) = (n-k+1)/k*C(n,k-1),递推求组合数
#include <bits/stdc++.h> using namespace std; const int MOD = 1e9+7; const int maxn = 1e3; typedef long long ll; int n,k; ll C[maxn]; int main() { n = 6; memset(C,0,sizeof(C)); C[0] = 1; for(int i = 1; i <= n; i++) { C[i] = C[i-1]*(n-i+1)/i; } //输出C(6,4) printf("%lld\n",C[4]); return 0; }
据紫书上得:递推得时候应该是先乘再除,因为如果先除的话C[i-1]/i可能不是一个整数,但如果先乘的话,可能会爆long long。
实在担心会爆long long的话可以先约分。