Vijos1060. 盒子

试题请参见: 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值