P2822 [NOIP2016 提高组] 组合数问题
考察:组合数学
思路:
C[i][j] = C[i-1][j-1]+C[i-1][j],注意拿当前数+不拿当前数,和分苹果的划分方式不一样.当C[i][j] = 0,Sum[i][j] = 1,求前缀和i、j范围必须相同.
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int N = 2010; 6 int C[N][N],k,n,m,sum[N][N]; 7 void inits() 8 { 9 for(int i=0;i<=N-10;i++) 10 for(int j=0;j<=i;j++) 11 if(!j) C[i][j] = 1; 12 else C[i][j] = (C[i-1][j]+C[i-1][j-1])%k; 13 for(int i=0;i<=N-10;i++) 14 for(int j=0;j<=i;j++) 15 sum[i][j] = (C[i][j]==0?1:0); 16 for(int i=1;i<=N-10;i++) 17 for(int j=1;j<=N-10;j++) 18 sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]; 19 } 20 int main() 21 { 22 int n,m,T; 23 scanf("%d%d",&T,&k); 24 inits(); 25 while(T--) 26 { 27 scanf("%d%d",&n,&m); 28 printf("%d\n",sum[n][m]); 29 } 30 return 0; 31 }