2020camp-day6-

看样例猜正解,证明略(其实是不会),

#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
", dp[n]);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/2aptx4869/p/12216734.html