洛谷2822 组合数问题

来源:互联网 发布:sass编译是什么源码 编辑:程序博客网 时间:2024/05/28 15:42

来源

NOIP 2016 提高组 D2T1

题目描述

(公式太难打,自己看原题吧)
传送门

算法

暴力
50分拿好。。。
递推
注意到组合数的递推公式:

c[i][j]=c[i1][j]+c[i1][j1]

所以我们可以先把c表打出来,记得%k
然后判断这个数是否能被k整除,是的话就统计;
然后记录下(输入为i、j)的答案。
然后对于输入,直接输出即可。

代码

#include <cstdio>#include <iostream>#include <cstring>using namespace std;typedef unsigned long long LL;LL s[2010][2010],c[2010][2010]; //s[i][j]表示前i行j列有多少个j的约数  LL h[2010]; //第i行有多少个k的约数  int main(){    int t,k,n,m;    scanf("%d%d",&t,&k);    c[0][0]=1; //边界:C(0,0)=1;     for (int i=1;i<=2001;i++)    {        c[i][0]=1; //边界:C(i,0)=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]%k==0) h[i]++; //处理约数              s[i][j]=s[i-1][j]+h[i]; //累加s[i][j]            if (i==j) s[i][j]=s[i-1][j-1]+h[i]; //这里要特判          }     }    while (t--)    {        scanf("%d%d",&n,&m);        if (m>n) m=n; //注意特判         printf("%d\n",s[n][m]);    }    return 0;}

后记

这道题考到了组合数的递推公式,是一道不错的数论题。

原创粉丝点击