C++ & Pascal & Java ——NOIP2016提高组day2 t1——组合数问题

来源:互联网 发布:手机淘宝刷単软件 编辑:程序博客网 时间:2024/05/20 11:24

题目描述

组合数 表示的是从 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 的倍数。

样例数据 1

输入

1 2 
3 3

输出

1

样例数据 2

输入

2 5 
4 5 
6 7

输出


7

备注

【样例1说明】
在所有可能的情况中,只有 是 2 的倍数。

【数据规模与约定】


#include<stdio.h>int f[2001][2001],dna[2001][2001];inline int readint(){    int i=0,f=1;    char ch;    for(ch=getchar();ch<'0'||ch>'9';ch=getchar());     for(;ch>='0' && ch<='9';ch=getchar())        i=(i<<3)+(i<<1)+ch-'0';    return i*f;}int main(){int t,k,n,m,maxx,all;t=readint();k=readint();for(int i=0;i<=2000;++i) f[i][i]=1,f[i][1]=i;for(int i=3;i<=2000;++i)for(int j=2;j<i;++j){f[i][j]=f[i-1][j-1]+f[i-1][j];f[i][j]%=k;}for(int i=1;i<=2000;++i){maxx=0;for(int j=i;j<=2000;++j){if(f[j][i]%k==0) ++maxx;dna[j][i]=maxx;}}while(t--){all=0;n=readint();m=readint();for(int i=1;i<=m;++i)all+=dna[n][i];printf("%d\n",all);}return 0;}
vart,k,n,m,i,j,maxx,all : longint;f,d : array [ 0..2001 , 0..2001 ] of longint;begin        read ( t , k );        for i := 0 to 2000 do begin                f[i][i] := 1;                f[i][1] := i;        end;        for i := 3 to 2000 do                for j := 2 to i-1 do begin                        f[i][j] := f[i-1][j-1] + f[i-1][j];                        f[i][j] := f[i][j] mod k;                end;        for i := 1 to 2000 do begin                maxx := 0 ;                for j := i to 2000 do begin                        if ( f[j][i] mod k ) = 0 then inc ( maxx );                        d[j][i] := maxx;                end;        end;        for j := 1 to t do begin                all := 0;                read (n , m);                for i := 1 to m do                        all := all + d[n][i];                writeln ( all );        end;end. 

import java.util.*;public class Main{static int t,k,n,m,maxx,all;static int [][] f=new int[2001][2001];static int [][] dna=new int[2001][2001];public static void main(String[] args){Scanner input=new Scanner(System.in);t=input.nextInt();k=input.nextInt();for(int i=0;i<=2000;i++){f[i][i]=1;f[i][1]=i;}for(int i=3;i<=2000;i++)for(int j=2;j<i;j++){f[i][j]=f[i-1][j-1]+f[i-1][j];f[i][j]%=k;}for(int i=1;i<=2000;i++){maxx=0;for(int j=i;j<=2000;j++){if(f[j][i]%k==0) ++maxx;dna[j][i]=maxx;}}while(t>0){--t;all=0;n=input.nextInt();m=input.nextInt();for(int i=1;i<=m;i++)all+=dna[n][i];System.out.println(all);}}}