AtCoder Beginner Contest 217 G - Groups(dp)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 217 G - Groups(dp)相关的知识,希望对你有一定的参考价值。
有 n n n个人分为 k k k组
其中两个人 i , j i,j i,j如果满足 i % m = j % m i\\%m=j\\%m i%m=j%m就不能分在一个组
求当 k ∈ [ 1 , n ] k\\in[1,n] k∈[1,n]时的方案数
定义 f [ i ] [ j ] f[i][j] f[i][j]表示前 i i i个人分成 j j j组的方案数,我们每次只考虑第 i i i个人放在哪个位置
f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] + f [ i − 1 ] [ j ] ∗ ( j − ⌊ i − 1 m ⌋ ) f[i][j]=f[i-1][j-1]+f[i-1][j]*(j-\\lfloor\\frac{i-1}{m}\\rfloor ) f[i][j]=f[i−1][j−1]+f[i−1][j]∗(j−⌊mi−1⌋)
自己新开一组就是 f [ i − 1 ] [ j − 1 ] f[i-1][j-1] f[i−1][j−1],否则不能和前面的 ⌊ i − 1 m ⌋ \\lfloor\\frac{i-1}{m}\\rfloor ⌊mi−1⌋个和自己同类型的人在一个组内
这样做的复杂度是 O ( n 2 ) O(n^2) O(n2)
#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
const int maxn = 5009;
int n,m,f[maxn][maxn];
int main()
{
cin >> n >> m;
f[0][0] = 1;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
{
f[i][j] = f[i-1][j-1];
if( j-(i-1)/m>=0 )
f[i][j] = ( 1ll*f[i][j]+1ll*f[i-1][j]*( j-(i-1)/m ) )%mod;
}
for(int i=1;i<=n;i++)
cout << f[n][i] << endl;
}
以上是关于AtCoder Beginner Contest 217 G - Groups(dp)的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder Beginner Contest 115 题解