2020camp-day6-J

dp[i],为在前n个数中,循环节为k(题目给的)的方案数

#include<cstdio>
#include<cstring>
#include<algorithm>

#define RE register
#define FOR(i,a,b) for(RE int i=a;i<=b;++i)
#define ROF(i,a,b) for(RE int i=a;i>=b;--i)
#define ll long long
#define sc(n) scanf("%d",&n)

using namespace std;

const int maxn = 1005;
const int mod = 998244353;

int n, T;
ll c[55], cn[55][55], dp[55], k;

void init()
{
    FOR(i, 0, 50)
    {
        cn[i][0] = 1;
        FOR(j, 1, i)cn[i][j] = (cn[i - 1][j - 1] + cn[i - 1][j]) % mod;
    }
    c[0] = c[1] = 1;
    FOR(i, 2, 50)c[i] = c[i - 1] * i % mod;
}

int main()
{
    init();
    sc(T);
    while(T--)
    {
        sc(n), scanf("%lld",&k);
        memset(dp, 0, sizeof(dp));
        dp[1] = dp[0] = 1;
        FOR(i,2,n)
            FOR(j,1,i)
                if (k % j == 0)
                    //为什么不是A(i,j)?而是A(i-1,j-1)
                    //把i中一个数提出来,让剩下的(i-1)个数挑一个k扔进去,在把(i-2)数中挑一个扔进k的位置。。。直到最后把最先挑出的数放进去
                    dp[i] = (dp[i] + (cn[i - 1][j - 1]) * c[j - 1] % mod * dp[i - j] % mod) % mod;
        printf("%lld\n", dp[n]);
    }
    return 0;
}

  

posted @ 2020-01-20 09:47  洛绫璃  阅读(129)  评论(0编辑  收藏  举报