P2822 组合数问题
P2822 组合数问题
其实以0行0列开始,在杨辉三角形里,每个数字对应一个组合数
1 //(0,0)
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
这样:
C33=1 C43=4
其实题面的意思就是:
以Cnm为右下角的数字,求它所在矩形里k的倍数有几个
代码
#include<iostream> #include<cstring> #include<cstdio> #include<cctype> #define ll long long #define gc() getchar() #define maxn 2005 using namespace std; inline ll read(){ ll a=0;int f=0;char p=gc(); while(!isdigit(p)){f|=p=='-';p=gc();} while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();} return f?-a:a; } void write(ll a){ if(a>9)write(a/10); putchar(a%10+'0'); } int t,k,c[maxn][maxn],f[maxn][maxn]; int main(){ t=read();k=read(); for(int i=0;i<=2000;++i)c[i][0]=1; for(int i=1;i<=2000;++i) for(int j=1;j<=i;++j) c[i][j]=(c[i-1][j-1]+c[i-1][j])%k; //预处理杨辉三角形 for(int i=1;i<=2000;++i)
{ for(int j=1;j<=i;++j)
{ f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]; if(!c[i][j])f[i][j]++; } f[i][i+1]=f[i][i]; } for(int i=1;i<=t;++i){ int n=read(),m=read(); if(m>n)m=n; write(f[n][m]); putchar('\n'); } return 0; }
特别鸣谢:hmr dalao