求排列组合数C(n,r)
#include<iostream>
#include<limits>
using namespace std;
/*
这是一个求组合数C(n,r)的算法程序。
*/
/*
杨辉三角:
0 1
1 1 1
2 1 2 1
3 1 3 3 1
4 1 4 6 4 1
5 1 5 10 10 5 1
0 1 2 3 4 5
C(n,r) =C(n-1,r)+C(n-1,r-1)
以C(5,3)为例:
C_Matrix[r+1][n-r+1]
(n-r+1)
1 1 1
(r+1) 1 2 3 C(n-1.r-1)
1 3 6 |
1 4 10 /|\
|
C(n-1,r)<---C(n,r)
C_Matrix[r][n-r]=C(n,r);
*/
//复杂度O(r*(n-r))
long **C_Matrix;
long C_n_r_version1(int n, int r){
if (r > n) return 0;
//创建备忘录
C_Matrix = new long*[r + 1];
for (int i(0); i < (r + 1); i++){
C_Matrix[i] = new long[n - r + 1];
}
//用1初始化第一行和第一列
for (int row1(0); row1 < (n - r + 1); row1++) C_Matrix[0][row1] = 1;
for (int column1(0); column1 < r + 1; column1++) C_Matrix[column1][0] = 1;
//自底向上迭代求解 C(n,r) =C(n-1,r)+C(n-1,r-1)
for (int row(1); row < r + 1; row++)
for (int column(1); column < (n - r + 1); column++)
C_Matrix[row][column] = C_Matrix[row][column - 1] + C_Matrix[row - 1][column];
return C_Matrix[r][n - r];
}
long C_n_r_version2Helper(int n, int r, long **CMatrix2){
if (CMatrix2[r][n-r]!=LONG_MIN){
return CMatrix2[r][n - r];
}
//自顶向下递归求解 C(n,r) =C(n-1,r)+C(n-1,r-1)
return CMatrix2[r][n - r] = C_n_r_version2Helper(n - 1, r, CMatrix2) + C_n_r_version2Helper(n - 1, r-1, CMatrix2);
}
//复杂度O(r*(n-r))
long **C_Matrix2;
long C_n_r_version2(int n, int r){
if (r > n) return 0;
//创建备忘录
C_Matrix2 = new long*[r + 1];
for (int i(0); i < (r + 1); i++){
C_Matrix2[i] = new long[n - r + 1];
}
//用1初始化第一行和第一列
for (int row1(0); row1 < (n - r + 1); row1++) C_Matrix2[0][row1] = 1;
for (int column1(0); column1 < r + 1; column1++) C_Matrix2[column1][0] = 1;
//用负无穷初始化其他数
for (int row(1); row < r + 1; row++)
for (int column(1); column < (n - r + 1); column++)
C_Matrix2[row][column] = LONG_MIN;
//转到递归调用
return C_n_r_version2Helper(n, r, C_Matrix2);
}
int main(){
int n, r;
cout << "输入C(n,r)中的n和r,以空格间分隔:" << endl;
cin >> n >> r;
cout << "C_n_r_version1的结果:" << C_n_r_version1(n, r)<<endl;
cout << "C_n_r_version2的结果:" << C_n_r_version2(n, r) << endl;
system("pause");
}
辅助图示: