组合数学
题意:有两种不同的球,放入n个箱子中,箱子可以放,也可以不放
分析:这是一种经典组合题,即往盒子中装球,我们由小学奥数可以得出结论:
( ext{ans = }sum^{a}_{i = 0} sum^{b}_{j = 0} ext{C[i + n - 1][n - 1] C[j + n - 1][n - 1]})
我们得到公式后,还需要一个高效计算组合数的算法,这是我们便想到了杨氏三角:
众所周知
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
.........
于是我们得到了一个公式:
C[i][j] = C[i - 1][j - 1] + C[i - 1][j]
其中当j == 0 || j == i
时,C[i][j] = 1
得到了一段预处理组合数的代码:
void Pre_Work() {
for(int i = 0; i <= 50; i ++) con[i][0] = con[i][i] = 1;
for(int i = 2; i <= 50; i ++)
for(int j = 1; j <= i; j ++)
con[i][j] = con[i - 1][j] + con[i - 1][j - 1];
}
#include <cstdio>
#include <iostream>
#define int unsigned long long
//注意要用ull
using namespace std;
int read() {
int w = 1,res = 0;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') w = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') res = res * 10 + ch - '0', ch = getchar();
return w * res;
}
int con[100][100], ans;
void Pre_Work() {
for(int i = 0; i <= 50; i ++) con[i][0] = con[i][i] = 1;
for(int i = 2; i <= 50; i ++)
for(int j = 1; j <= i; j ++)
con[i][j] = con[i - 1][j] + con[i - 1][j - 1];
}
signed main() {
int n = read(), a = read(), b = read();
Pre_Work();
for(int i = 0; i <= a; i ++)
for(int j = 0; j <= b; j ++)
ans += con[i + n - 1][n - 1] * con[j + n - 1][n - 1];
cout << ans;
return 0;
}