试题请参见: https://vijos.org/p/1060
题目概述
N个盒子排成一行(1<=N<=20). 你有A个红球和B个蓝球. 0 <= A <= 15, 0 <= B <= 15. 球除了颜色没有任何区别. 你可以将球放进盒子. 一个盒子可以同时放进两种球, 也可以只放一种, 也可以空着. 球不必全部放入盒子中. 编程计算有多少种放置球的方法.
输入
一行, N, A, B, 用空格分开.
输出
一行, 输出放置方案总数.
解题思路
1. 组合数学问题, 用隔板法;
2. 因为允许球不放完, 因此我们可以假设有n + 1个盒子, 其中多的那个盒子放置未放完的球;
3. 又因为允许盒子为空, 这不符合隔板法的前提, 因此我们需要加上n个球, 以保证每个盒子至少有一个球.
4. 于是问题就简化为, 将x + n个小球放入n + 1个盒子, 则有n个间隔, 即C(n, x + n)
遇到的问题
(第5个测试点AC不了, 可是我本地测试的结果与预期结果完全一致.)
1. 注意精度问题, 一定要用unsigned long long.
2. 计算C(x, y)的时候记得转换为浮点类型计算, 以免小数部分被忽略.
源代码
#include <iostream>
int main() {
int n = 0, a = 0, b = 0;
std::cin >> n >> a >> b;
unsigned long long totalA = 1, totalB = 1;
for ( int i = 1; i <= a; ++ i ) {
totalA *= (n + i) / (i * 1.0);
}
for ( int i = 1; i <= b; ++ i ) {
totalB *= (n + i) / (i * 1.0);
}
std::cout << totalA * totalB << std::endl;
return 0;
}