組合數問題
阿新 • • 發佈:2017-06-25
一個數 bsp 最大 des blog scan using std clu
組合數問題
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]]); } }
組合數問題