一道组合数与约数结合的题目。跑杨辉三角即可。但是充分跑多次会超时,要用前缀和维护下,维护一维也能过,维护二维更好。注意维护二维的时候要过了对角线多跑一个。
知识点:杨辉三角+二维前缀和
#include<iostream>
#include<stdio.h>
using namespace std;
const int N=2009;
int t,k,n,m,cn[10009],cm[10009],c[N][N],dp[N][N],maxn=0,maxm=0;
int main(){
scanf("%d%d",&t,&k);
for(int i=0;i<t;i++){
scanf("%d%d",&cn[i],&cm[i]);
if(cm[i]>cn[i])cm[i]=cn[i];
}
c[1][1]=1;
if(c[1][1]%k==0)dp[1][1]=1;
for(int i=2;i< N;i++){
for(int j=1;j<=i;j++){
c[i][j]=(c[i-1][j-1]+c[i-1][j])%k;
dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
if(c[i][j]==0)dp[i][j]++;
// cout<<c[i][j]<<" ";
}
dp[i][i+1]=dp[i][i];
// cout<<endl;
}
/* for(int i=2;i<=11;i++){
cout<<"i"<<i<<" ";
for(int j=1;j<=i+1;j++){
cout<<dp[i][j]<<" ";
}
cout<<endl;
}
*/
for(int i=0;i<t;i++){
int ans=0;
n=cn[i],m=cm[i];
printf("%d\n",dp[n+1][m+1]);
}
}
参考代码