[ABC217]G

[ABC217]G - Groups

题目

(n)个人,编号(isim n),分成(k)组(不一定要连续分组),使任意一组内不存在两个人的编号模(m)同余,问方案,取模.

输入(n,m),输出(k)(1sim n)的所有答案.

思路

这题不比F水?

(f_{i,j})表示前(j)个人,分成(i)组的合法方案数,目标显然为(f_{i,n},quad iin[1,n]).

考虑从前(j-1)个人转移,对于第(j)个人,有两种方案:

  1. 单独开一个组,贡献是(f_{i-1,j-1})
  2. 放到前面的某一个组,注意,前面有(i)个组,但是有(lfloor frac{j-1}m floor)个组中存在和(j)(m)同余的数,所以贡献是(f_{i,j-1}cdot (i-lfloor frac{j-1}m floor)).

转移是(O(1))的,复杂度就是(O(n^2)).

代码

#include <iostream>
#include <cstdio>
using namespace std;

typedef long long LL;
const LL mod = 998244353;
const int N = 5010;
int n , m;
LL f[N][N];

int main() {
	cin >> n >> m;
	for(int i = 1 ; i <= m ; i++)
		f[1][i] = 1;
	for(int i = 2 ; i <= n ; i++)//i groups
		for(int j = 1 ; j <= n ; j++) {//first j people
			f[i][j] = f[i - 1][j - 1] + f[i][j - 1] * (i - (j - 1) / m) % mod;
			f[i][j] %= mod;
		}
	
	for(int i = 1 ; i <= n ; i++) {
		printf("%d
" , f[i][n]);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/dream1024/p/15254152.html