知识共享许可协议

本题 由 Red 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
严禁抄袭,侵权必究。代码仅当参考使用。

挂彩灯

描述
有一堆彩灯,红色绿色两种颜色,现在要把它们串在一起,要求每个红灯后面至少要有1个绿灯,求一共有多少种不同的串法

输入
第1行是一个正整数n,表示测试案例的数量

第2到第n+1行是n组测试数据,每行数据有两个正整数,分别表示红灯的数量和绿灯的数量

输出
针对每行测试数据,输出不同的串法数量。(答案不会超过50万)

每组案例输出完都要换行。

样例输入
1

2 3

样例输出
3

提示说明
2个红灯3个绿灯合法的串法有:绿红绿红绿、红绿绿红绿、红绿红绿绿,一共3种

思路

高中排列组合题,应该来说思路是很直观的。

首先彩灯要遵循“一红配一绿”的规则,那么剩下需要进行排列的彩灯也就是用绿彩灯减去红彩灯数剩下的进行插空。那么问题就变成了十分经典的一种排列组合模型——将绿球排成一排,然后再从中挑出若干个与红球进行配对。因为根据题意,红球绝对不可能排在队头,所有这里只需要将 C(绿球数,红球数)算出来就行。并且根据排列组合C(m,n)=m!/n!*(m-n)!的特性,当红灯数大于绿灯数一半后,可以将超出部分消去,因此只需要对g-r进行计算就行
需要注意的是,为了防止数据超出,这里数据类型需要使用long long

代码[C++]

[Forlogin]
#include <iostream>
#include <cmath>
#include<limits.h>
using namespace std;
int main()
{
    int n;
    cin >> n;
    while (n--)
    {
        long long int r, g, c, mul1 = 1, mul2 = 1;
        cin >> r >> g;
        if (r > g)
        {
            cout << 0;
        }
        else if (r == g || r == 0)
        {
            cout << 1;
        }
        else
        {
            if (r > g / 2)
            {
                r = g - r;
            }
            for (int i = 1; i<=r; i++)
            {
                mul1 = mul1 * g;
                mul2 = mul2 * i;
                g--;
            }
            c = mul1 / mul2;
            cout << c;
        }
        cout << endl;
    }
    return 0;
}[/Forlogin]