组合数问题
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]]); } }
以上是关于组合数问题的主要内容,如果未能解决你的问题,请参考以下文章