[bzoj4465][DP][Number Theory] Learning in the game

Description

You must have seen a lot of people holding hands and dancing around a bonfire, right? Under normal circumstances, when everyone dances hand in hand, they will always form a big circle. Each person's left hand pulls the right hand of the friend next to him, and the right hand pulls the left hand of the friend on the other
side . However, things
get - at this point people will still form circles, but there may be multiple independent circle. Of course, here we still require that one person's right hand can only pull another person's left hand, and vice versa.
There are N students in the class, numbered from 1 to N. Will wants to know, how many essentially different handle solutions are there, so that in the end, when everyone spreads out, exactly k circles are formed?
Given two schemes, if there is a person and one of his hands, and if the number of the person holding the hand is different in the two schemes, then the two schemes are essentially different.

Input

Input a line containing three positive integers N, k and P. 3<=3k<=N<=3000, 10^4<=p<=2×10^9

Output

The output file contains one line with an integer representing the remainder of p for the number of substantially different schemes. It is guaranteed that p must be a prime number.

Sample Input

3 1 1000000009

Sample Output

2

answer

Let f[i][j] denote the number of schemes that have i persons and form j circles.
For the i-th person, consider the number of schemes
that he does not form a new circle, that is, f[i][j]=f[i-1 ][j]*(i-1), because there are i-1 vacancies
, when a new circle is formed, 2 people can be arbitrarily selected from the original circle, and the new circle formed has two schemes,
so f[ i][j]=f[i-3][j-1]*C(i-1)*2

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
LL f[3100][3100],mod;
int n,K;
int main()
{
    scanf("%d%d%lld",&n,&K,&mod);
    f[0][0]=1;
    for(int i=3;i<=n;i++)
        for(int j=1;3*j<=i&&j<=K;j++)
        {
            f[i][j]=f[i-1][j]*(i-1)%mod;
            f[i][j]=(f[i][j]+f[i-3][j-1]*(i-1)*(i-2))%mod;
        }
    printf("%lld\n",f[n][K]);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324686022&siteId=291194637