[洛谷P5259] 游戏中的学问

求环的一道dp题ios

求环DP的解法

对于本题来讲,对于每个造成的新环,都有两种状态中的一种状态转移而来spa

设定f[i][j]表明i我的造成j个环的方案数code

状态一:由f[i-1][j]转移过来,对于每个位置都有插空的可能性,因此须要×(n-1)blog

状态二:由f[i-3][j-1]转移过来,咱们能够获得在两个环组成一个新的环的时候,能够由i-3我的围成j-1个环,而后再选出两我的去拉手组成一个大环io

由于由i-1个的小环插入的时候须要×(i-1),而后对于i-3我的的时候插入就须要在这个基础上在×(i-2)  //这是显然的,由于这个组合是随机的,顺序均为单向class

Code:

#include<iostream>
#include<cstdio>
#define MAXN 2003
#define ll long long
using namespace std;
ll n,k,p;
ll dp[MAXN << 1][MAXN];
int main()
{
    scanf("%lld%lld%lld",&n,&k,&p);
    dp[0][0] = 1;
    for(ll i=1;i<=n;i++)
    for(ll j=1;j<=min(i / 3,k);j++)
    dp[i][j] = (dp[i - 1][j] * (i - 1) % p + dp[i - 3][j - 1] * (i - 1) * (i - 2) % p) % p;
    printf("%lld",dp[n][k]);
    return 0;
}
相关文章
相关标签/搜索