组合数问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组合数问题相关的知识,希望对你有一定的参考价值。

组合数问题

Description

技术分享

技术分享

科普:组合数公式:C(n,m)=C(n,m-1)+C(n-1,m-1)

对于一对n,m 可以用杨辉三角递推出C(n,m)

 

 

 

而这道题中由于 t<=104 不能直接进行求解

所以我们可以离线处理,具体操作如下:

1.对于每一次询问中的 i , j 分别取出对应的最大值 imax , jmax

2.利用组合数公式进行递推打表,维护一个数组s[i][j],如果C(i,j)是k的倍数,记s[i][j]=1;

3.利用二维前缀和 令s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]

 

 

 

最后对于每次询问可在O(1)时间内求出答案

 

 

#include<iostream>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
int t,k;
int c[2005][2005],sum[2005][2005],N[10005],M[10005],Nmax,Mmax,P;
int main()
{
    scanf("%d%d",&t,&k);;
    for(int i=1;i<=t;i++)
    {
        scanf("%d%d",&N[i],&M[i]);
        Nmax=max(Nmax,N[i]);
        Mmax=max(Mmax,M[i]);
    }
    c[0][0]=1;
    for(int i=1;i<=Nmax;i++)
    {
        c[i][0]=1;
        for(int j=1;j<=i;j++)
        {
            c[i][j]=(c[i-1][j]%k+c[i-1][j-1]%k)%k;
            if(c[i][j]==0) sum[i][j]=1;
        }
    }
    for(int i=0;i<=Nmax;i++)
        for(int j=0;j<=Mmax;j++)
            sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
    for(int i=1;i<=t;i++)
    {
        printf("%d\n",sum[N[i]][M[i]]);
    }
}

 

 


以上是关于组合数问题的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 代码片段

48个值得掌握的JavaScript代码片段(上)

片段组合在 Relay 中是如何工作的?

如何将片段中的 ListView 对象的数据传递给 Activity?

如何像浏览器一样在 Java 中组合 URL 片段?

使用 Apollo 客户端的片段组合:约定和样板