F - Keep Connect

F - Keep Connect --- UNIQUE VISION Programming Contest 2022(AtCoder Beginner Contest 248)

Editorial

solution

dp。定义dp[i][j][2],其中dp[i][j][1]表示前i列删除j条线联通图的方案数;dp[i][j][0]表示前i列删除j条线不连通图的方案数,该图中第i列中间线是不连接的,如果该线连接,那么该图则为连通图。
有以下状态转移方程:

\[\begin{cases} dp[i][j][0] = (dp[i][j][0] + dp[i-1][j-1][0] + 2*dp[i-1][j-2][1])\%p; \\ dp[i][j][1] = (dp[i][j][1] + dp[i-1][j][1] + 3*dp[i-1][j-1][1]+ dp[i-1][j][0])\%p; \end{cases} \]

code

#include <bits/stdc++.h>
using namespace std;
const int NMAX = 3e3 + 10;
typedef long long ll;
ll dp[NMAX][NMAX][2];

int main() {
    int n, p;
    scanf("%d%d", &n, &p);

    int ans = 0;
    dp[1][0][1] = dp[1][1][0] = 1;
    for(int i = 1;i <= n;i++) {
        for(int j = 0;j < n;j++) {
            dp[i][j][1] += dp[i-1][j][1] + (j > 0?3*dp[i-1][j-1][1]: 0) + dp[i-1][j][0];
            dp[i][j][0] += (j > 0?dp[i-1][j-1][0]: 0) + (j > 1? 2*dp[i-1][j-2][1]: 0);
            dp[i][j][1] %= p;
            dp[i][j][0] %= p;
        }
    }

    for(int i = 1;i < n;i++)    printf("%lld%c", dp[n][i][1], i == n-1?'\n': ' ');
    return 0;
}
posted @ 2022-04-19 17:08  jadelemon  阅读(48)  评论(0编辑  收藏  举报