列表

详情


NC16429. [NOIP2016]组合数问题

描述

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



其中

小葱想知道如果给定 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 的倍数。

示例1

输入:

1 2
3 3

输出:

1

示例2

输入:

2 5
4 5
6 7

输出:

0
7

说明:

在所有可能的情况中,只有是 2 的倍数。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 47ms, 内存消耗: 34660K, 提交时间: 2020-03-14 09:45:40

#include <bits/stdc++.h>
using namespace std;
int c[3000][3000];
int summ[3000][3000];

int main()
{
	int t,k; cin >> t >> k;
	int a,b;
	int w = 0;
	for(int i = 0; i <= 2100; i++)
	{
		w = 0;
		c[i][0] = c[i][i] = 1;
		for(int j = 1; j < i; j++)
		{
			c[i][j] = (c[i-1][j]+c[i-1][j-1])%k;
			if(c[i][j] == 0) w++;
			summ[i][j] = summ[i-1][j]+w;
		}
		summ[i][i] = summ[i][i-1];
	}
	while(t--)
	{
		cin >> a >> b;
		cout<<summ[a][min(a,b)]<<endl;
	}
	return 0;
}

C 解法, 执行用时: 43ms, 内存消耗: 29872K, 提交时间: 2023-01-17 11:37:20

#include <stdio.h>
const int M=2005;
int main(){
    int t,k,n,m,C[M][M],sum[M][M];
	scanf("%d%d",&t,&k);
	for(int i=1;i<=2000;i++){
		C[i][0]=C[i][i]=1;
		for(int j=1;j<i;j++)
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%k; 
	}
	for(int i=1; i<=2000; i++)
		for(int j=1;j<=2000;j++){
			int x = 0;
			if(i>=j) x=(C[i][j]==0);
			sum[i][j]=sum[i-1][j]+sum[i][j-1]+x-sum[i-1][j-1];
		}
		while(t--){
			scanf("%d%d",&n,&m);
			printf("%d\n",sum[n][m]);
		}	
		return 0;
} 

C++11(clang++ 3.9) 解法, 执行用时: 76ms, 内存消耗: 30040K, 提交时间: 2019-11-09 11:49:59

#include <bits/stdc++.h>
using namespace std;
int c[2001][2001],ans[2001][2001],n,m,t,k;
int main() {
	cin>>t>>k;
	c[0][0]=1;
	for(int i=1; i<=2000; i++) {
		c[i][0]=1;
		for(int j=1; j<=2000; j++) {
			if(i>=j) {
				c[i][j]=(c[i-1][j-1]+c[i-1][j])%k;
				if(c[i][j]==0)ans[i][j]=1;
			}
			ans[i][j]+=ans[i-1][j]+ans[i][j-1]-ans[i-1][j-1];
		}
	}
	while(t--){
		cin>>n>>m;
		cout<<ans[n][m]<<endl;
	}
	return 0;
}

上一题