Day2 T1
題目大意
告訴你組合數公式
,其中n!=1*2*3*4*5*...*n;意思是從n個物體取出m個物體的方案數
現給定n、m、k,問在所有i(1<=i<=n),所有j(1<=j<=min(i,m))的(i,j)滿足Cji是k的倍數的個數。
輸入樣例:
2 5 (兩個數,第一個數t表示該數據有t組詢問,第二個為k,接下來t行分別為n,m) 4 5 6 7
輸出樣例:
0 7
數據范圍:1<=n,m<=2000,1<=t<=10000,1<=k<=21
數論題,當時做竟然沒發現這就是個楊輝三角,就是少了第一列全是1的,真是悲劇。
組合數的遞推式就是Cmn=Cm-1n-1+Cmn-1
因為k一開始就固定了,所以預處理2000以內的個數,用前綴和優化優化就可以AC了,當然用二維前綴和似乎能優化到O(1),不麻煩每行一個前綴和到時候O(n)的得出答案也不會超時。
比完賽了也趕快轉C++了23333
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 int a[2005][2005],ji[2005][2005]; 7 int n,m,ans,t,k; 8 int main(){ 9 scanf("%d%d",&t,&k); 10 memset(a,0,sizeof(a)); 11 a[1][1]=1%k; 12 if (a[1][1]==0) ji[1][1]++; 13 for (int j=2;j<=2001;j++) 14 for (int q=1;q<=min(j,2001);q++){ 15 if (q==1) a[j][q]=(a[j-1][q]+1)%k; 16 else a[j][q]=(a[j-1][q]+a[j-1][q-1])%k; 17 if (a[j][q]==0) ji[j][q]=ji[j][q-1]+1; else ji[j][q]=ji[j][q-1]; 18 } 19 for (int i=1;i<=t;i++){ 20 scanf("%d%d",&n,&m); 21 ans=0; 22 for (int j=1;j<=n;j++) 23 ans+=ji[j][min(m,j)]; 24 printf("%d\n",ans); 25 } 26 return 0; 27 }
