【C++】组合数

这篇文章介绍了一个编程问题,涉及计算从n个物品中选择m个且满足特定条件(是k的倍数)的组合数对。程序使用了递推和模运算的方法来存储并计算结果,适用于C++环境。
题目描述

组合数表示的是从n个物品中选出m个物品的方案数。举个例子,从 (1, 2, 3) 三个物品中选择两个物品可以有 (1, 2),(1, 3),(2, 3) 这三种选择方法。
根据组合数的定义,我们可以给出计算组合数的一般公式:
 


其中 n!=1×2×⋯×n。
吴晗想知道如果给定n,m和k,对于所有的0 ≤ i ≤ n, 0 ≤ j ≤ min(i,m) 有多少对 (i, j) 满足

是k的倍数。

输入

第一行有两个整数t,k,其中t表示该测试点总共有多少组测试数据,k的意义见「题目描述」。
接下来t行每行两个整数n,m,其中n,m的意义见「题目描述」。

输出

输出共t行,每行一个整数代表对于所有的 0 ≤ i ≤ n, 0 ≤ j ≤ min(i,m) 有多少对 (i, j) 满足

是k的倍数。

#include <iostream>
long long nums[2010][2010], ans[2010][2010];
int t, n, m, k;
void fun()
{
	nums[1][1] = 1;
	for (int i = 0; i <= 2006; i++)
	{
		nums[i][0] = 1;
		for (int j = 1; j <= i; j++)
		{
			nums[i][j] = (nums[i - 1][j] % k + nums[i - 1][j - 1] % k) % k;
			ans[i][j] = ans[i - 1][j] + ans[i][j - 1] - ans[i - 1][j - 1];
			if (nums[i][j] == 0) ans[i][j]++;
		}
		ans[i][i + 1] = ans[i][i];
	}
}
int main()
{
	scanf("%d%d", &t,&k);
	fun();
	while (t--)
	{
		scanf("%d%d", &n, &m);
		printf("%lld\n", ans[n][std::min(m, n)]);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值