1. 程式人生 > >洛谷 P2822 組合數問題 如題

洛谷 P2822 組合數問題 如題

opened 答案 gif image pan alt urn pla spl

P2822 組合數問題

  • 時空限制1s / 512MB

題目描述

組合數C_n^mCnm?表示的是從n個物品中選出m個物品的方案數。舉個例子,從(1,2,3) 三個物品中選擇兩個物品可以有(1,2),(1,3),(2,3)這三種選擇方法。根據組合數的定 義,我們可以給出計算組合數的一般公式:

C_n^m=\frac{n!}{m!(n - m)!}Cnm?=m!(nm)!n!?

其中n! = 1 × 2 × · · · × n

小蔥想知道如果給定n,m和k,對於所有的0 <= i <= n,0 <= j <= min(i,m)有多少對 (i,j)滿足C_i^jCij?是k的倍數。

輸入輸出格式

輸入格式:

第一行有兩個整數t,k,其中t代表該測試點總共有多少組測試數據,k的意義見 【問題描述】。

接下來t行每行兩個整數n,m,其中n,m的意義見【問題描述】。

輸出格式:

t行,每行一個整數代表答案。

輸入輸出樣例

輸入樣例#1: 復制
1 2
3 3
輸出樣例#1: 復制
1
輸入樣例#2: 復制
2 5
4 5
6 7
輸出樣例#2: 復制
0
7

說明

【樣例1說明】

在所有可能的情況中,只有C_2^1 = 2C21?=2是2的倍數。

【子任務】

技術分享

--------------------------------------------------------------------------------------------------------------------------

寫這道題之前,首先要知道二項式定理、楊輝三角、組合數公式以及它們之間的關系

題目給你組合數公式,難不成直接計算?不存在的。看數據範圍就知道了

就是利用楊輝三角及二項式定理求組合數的過程

得出的遞推式為:

技術分享

詳細見代碼:

技術分享
 1 #include<stdio.h>
 2 #include<iostream>
 3
#define maxn 2010 4 using namespace std; 5 int t,k,n,m,s[maxn][maxn],ans,f[maxn][maxn]; 6 int main(){ 7 scanf("%d %d",&t,&k); 8 for(int i=0;i<maxn;i++) s[i][0]=s[i][i]=1;//邊界值,把楊輝三角寫出來就知道了 9 for(int i=1;i<maxn;i++) 10 for(int j=1;j<maxn;j++) 11 if(i>=j){ 12 s[i][j]=(s[i-1][j-1]+s[i-1][j])%k;//算出來的值可能很大,所以需要在這裏取摸 13 f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1];//f[i][j]即子問題的解,這裏是二維前綴和 14 if(!s[i][j]) f[i][j]++; 15 } 16 else f[i][j]=f[i][i]; 17 for(int i=1;i<=t;i++){ 18 scanf("%d %d",&n,&m); 19 printf("%d\n",f[n][m]); 20 } 21 return 0; 22 }
組合數

洛谷 P2822 組合數問題 如題