P2822组合数问题

题目链接

写在前面

众所周知,小葱同学擅长计算,尤其擅长计算组合数。而且这道题与组合数有关系。

乍一看什么思路没有,硬想柿子想了半小时。

不知道结论,wtcl。

后来打表发现规律,发现是个非常水的规律题,然后5min写完 + 3min调代码交上去AC了。

题外话:自己写的快读挂了。

Solution

\(k\) 下的杨辉三角,值为 \(0\) 的位置权值为 \(1\),最后统计答案的时候用一下二维前缀和即可。

Code:

#include<bits/stdc++.h>
#define LL long long
using namespace std;

const int Maxn = 2e3 + 5;

int a[Maxn][Maxn];
int b[Maxn][Maxn];

int t, k, m, n;
 
/*inline int read()
{
	int fh = 1, x = 0;
	char ch;
	while(ch!='-'&&!isdigit(ch)) ch = getchar();
	while(ch == '-') fh = - fh, ch = getchar();
	while(isdigit(ch)) ch = getchar(), x = (x << 3) + (x << 1) + ch ^ '0';
	return fh * x;
}*/

void init()
{
	for(int i = 0; i <= 2000; ++i)
	{
		a[i][0] = 1;
	}
	for(int i = 1; i <= 2000; ++i)
	{
		for(int j = 1; j <= i; ++j)
		{
			a[i][j] = (a[i - 1][j - 1] % k) + (a[i - 1][j] % k);
			a[i][j] %= k;
			if(!a[i][j]) b[i][j] = 1;
		}
	}
	for(int i = 1; i <= 2000; ++i)
	{
		for(int j = 1; j <= 2000; ++j)
		{
			b[i][j] = b[i][j] + b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];
		}
	}
}

int main()
{
	scanf("%d%d", &t, &k);
	init();
	while(t--)
	{
		scanf("%d%d", &n, &m);
		printf("%d\n", b[n][m]);
	}
	return 0;
} 

学到了什么

  • 看到这种题目果断手算规律。
posted @ 2020-09-13 17:22  zimujun  阅读(133)  评论(1编辑  收藏  举报