codechef : Marbles 题解

Rohit dreams he is in a shop with an infinite amount of marbles. He is allowed to select n marbles. There are marbles of k different colors. From each color there are also infinitely many marbles. Rohit wants to have at least one marble of each color, but still there are a lot of possibilities for his selection. In his effort to make a decision he wakes up.
Now he asks you how many possibilities for his selection he would have had.
Assume that marbles of equal color can't be distinguished, and the order of the marbles is irrelevant.

Input


The first line of input contains a number T <= 100 that indicates the number of test cases to follow. Each test case consists of one line containing n and k, where n is the number of marbles Rohit selects and k is the number of different colors of the marbles. You can assume that 1<=k<=n<=1000000.

Output


For each test case print the number of possibilities that Rohit would have had.
You can assume that this number fits into a signed 64 bit integer.

Example

Input:
2
10 10
30 7

Output:
1
475020

本题是一题组合数学的题目。应用到比较高级一点的数学知识。

可以认为是一题indistinguishable objects to distinguishable boxes 把相同的物体放进不同盒子的问题。

这样应用公式是:C(n, n+k-1) = C(k-1, n+k-1),n代表物体k代表盒子

但是因为需要每个盒子最少必须放置一个物体,故此减去每个盒子的这一个球,就得到公式:C(k-1, n+k-1-k)

这样就可以简化为计算一个公式的问题了。

注意: 这里是相同物体放进不同盒子,所以比较简单,注意区分不同物体放进不同盒子中。

#include <stdio.h>
#include <math.h>
#include <algorithm>
using std::min;

class Marbles
{
	long long C(int n, int k)
	{
		long long ans = 1LL;
		k = min(k, n-k);
		for (int i = 1; i <= k; i++)
		{
			ans *= (n-i+1);
			ans /= i;//这里肯定是可以除尽的,所以不用判断
		}
		return ans;
	}
public:
	Marbles()
	{
		int T, nsel, kcol;
		scanf("%d", &T);
		while (T--)
		{
			scanf("%d %d", &nsel, &kcol);//kcol <= nsel
			if (nsel < kcol)
			{
				puts("0");
				continue;
			}
			int n = nsel + kcol - 1 - kcol;
			int k = kcol - 1;
			printf("%lld\n", C(n, k));
		}
	}
};



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值