1. 程式人生 > >組合數打表+二維字首陣列優化——組合數問題

組合數打表+二維字首陣列優化——組合數問題

題目來源

洛谷P2822組合數問題

https://www.luogu.org/problem/show?pid=2822

思路

輸入t和k之後 預處理一個模k意義下的2000的楊輝三角表

字首陣列num[n][m]記錄C(0,0)~C(n,m)的矩形中有意義且(%k後)為0的組合數的數量

可以證得num[i][j]即為題中所求的對於所有的0<=i<=n,0<=j<=min(i,m)中滿足C(i,j)是k的倍數的(i,j)的數量。


C_n^m

程式碼(C++)


C_n^m
~

C_n^

#include <cstdio>
using namespace std;
int T,k,n,m,s,yh[2010][2010];
long long num[2010][2010];
inline void preyhsj();//預處理 
int main()
{
	scanf("%d%d",&T,&k);
	preyhsj();
	for(int t=1;t<=T;++t)
	{
		scanf("%d%d",&n,&m);
		printf("%lld\n",num[n][m]);
	}
	return 0;
}
inline void preyhsj()
{
	yh[0][0]=1;
	for(int i=1;i<=2000;++i)
	{
		yh[i][0]=1;	yh[i][i]=1;	s=0;
		for(int j=1;j<=i;++j)
		{
			yh[i][j]=(yh[i-1][j-1]+yh[i-1][j])%k;
			if(yh[i][j]==0)
				++s;
			num[i][j]=num[i-1][j]+s;
		}
		for(int j=i+1;j<=2000;++j)
			num[i][j]=num[i][j-1];
	}
	return ;
}