[洛谷P5259] 遊戲中的學問

求環的一道dp題

求環DP的解法

對於本題來說,對於每一個形成的新環,都有兩種狀態中的一種狀態轉移而來

設定f[i][j]代表i個人形成j個環的方案數

狀態一:由f[i-1][j]轉移過來,對於每一個位置都有插空的可能性,所以需要×(n-1)

狀態二:由f[i-3][j-1]轉移過來,我們可以得到在兩個環組成一個新的環的時候,可以由i-3個人圍成j-1個環,然後再選出兩個人去拉手組成一個大環

因爲由i-1個的小環插入的時候需要×(i-1),然後對於i-3個人的時候插入就需要在這個基礎上在×(i-2)  //這是顯然的,因爲這個組合是隨機的,順序均爲單向

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章