递归版本,利用公式c(n,m)=c(n-1,m)+c(n-1,m-1)
意义: 从n里面取m的方法,一种是取了当前元素,那么再从剩下的n-1个里面取m-1个(因为已经取了一个),另一种是没有取当前元素,那么再从剩下的n-1个里面取m个
int combine1(int n, int m){
if (n < m)return -1;
if (m == 0)return 1;
if (m == 1)return n;
if (m == n)return 1;
return combine1(n - 1, m - 1) + combine1(n - 1, m);
}
非递归版本,利用公式(c(n,m)=c(n-1,m)+c(n-1,m-1))+动态规划
int combine3(int n, int m){
if (n < m)return -1;
vector<vector<int>> temp(n + 1, vector<int>(m + 1, 0));
for (int i = 0; i <= n; ++i){
temp[i][0] = 1;
if (i <= m)
temp[i][i] = 1;
temp[i][1] = i;
}
temp[1][1] = 1;
for (int i = 3; i <= n; ++i)
for (int j = 2; j <= m&&j <= i; ++j){
temp[i][j] = temp[i - 1][j - 1] + temp[i - 1][j];
}
int result = temp[n][m];
return result;
}
非递归版本:利用公式c(n,m)=n! /(m!*(n-m)!)
int combine4(int n, int m){
if (n < m)return -1;
int temp1 = 1;
int temp2 = 1;
if (m>n / 2)m = n - m;
for (int i = n; i >= n - m + 1; --i)
temp1 *= i;
for (int i = 1; i <=m; ++i)
temp2 *= i;
return temp1 / temp2;;
}