组合数问题
题面
Description
Input
Output
Sample Input
Sample Input1:
1 2
3 3
Sample Input2:
2 5
4 5
6 7
Sample Output
Sample Output1:
1
Sample Output2:
0
7
Data Constraint
思路
这题找一下规律可以很容易发现,它是杨辉三角形。所以我们只需要在 O ( n m ) O(nm) O(nm)的复杂度内预处理出一个杨辉三角,将每个数 ( m o d k ) \pmod k (modk),如果它为0,表示它是k的倍数,用二维前缀和处理一下即可。
查询时间复杂度为 O ( 1 ) O(1) O(1),所以时间复杂度为 O ( t + n m ) O(t+nm) O(t+nm)。
Code
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
int t,k,n,m,f[2005][2005],a[2005][2005];
int main()
{
freopen("problem.in","r",stdin);
freopen("problem.out","w",stdout);
scanf("%d%d",&t,&k);
a[0][0]=1%k;
if(!a[0][0]) f[0][0]=1;
for(int i=1;i<=2000;i++)
for(int j=0;j<=2000;j++)
{
if(j<=i)
{
if(j==0||j==i) a[i][j]=1%k;
else a[i][j]=(a[i-1][j-1]+a[i-1][j])%k;
}
int bz=0;
if(!a[i][j]&&j<=i) bz=1;
f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+bz;
}
for(int i=1;i<=t;i++)
{
scanf("%d%d",&n,&m);
printf("%d\n",f[n][m]);
}
return 0;
}