首页 > 代码库 > 组合数问题
组合数问题
组合数问题
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]]); } }
组合数问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。