题解
组合数公式:
c[i][j]=c[i-1][j]+c[i-1][j-1]
打表发现其实就是杨辉三角,不过这样好像只有60分
优化:1.边计算边取模
2.用前缀和思想,ans[ ][ ]表示满足条件的个数
if(c[i][j]%k==0)ans[i][j]=1;
else ans[i][j]=0;
ans[i][j]=(ans[i][j]+ans[i][j-1]+ans[i-1][j]-ans[i-1][j-1])%k;
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=2005;
int n,m,k,t;
int f[N][N],ans[N][N];
int read(){
int sum=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
sum=(sum<<3)+(sum<<1)+ch-'0';
ch=getchar();
}
return sum*f;
}
int main(){
// freopen("problem.in","r",stdin);
// freopen("problem.out","w",stdout);
t=read();
k=read();
f[0][0]=1;
f[1][0]=f[1][1]=1;
for(int i=2;i<=2001;i++)
{
f[i][0]=1;
for(int j=1;j<=i;j++)
{
f[i][j]=f[i-1][j-1]+f[i-1][j];
f[i][j]%=k;
ans[i][j]=ans[i-1][j]+ans[i][j-1]-ans[i-1][j-1];
if(!f[i][j])ans[i][j]++;
}
ans[i][i+1]=ans[i][i];
}
while(t--)
{
n=read();
m=read();
if(m>n)cout<<ans[n][n]<<endl;
else cout<<ans[n][m]<<endl;
}
return 0;
}