AtCoder Beginner Contest 244 E - King Bombee(動態規劃)
阿新 • • 發佈:2022-03-25
原題連線:https://atcoder.jp/contests/abc244/tasks/abc244_e
官方題解:https://atcoder.jp/contests/abc244/editorial/3619
題意
簡單無向圖,n個點,m條邊。從S到T經過K條邊,X出現的數量是偶數,一共有多少種方案
思路
-
先不考慮x出現的數量為偶數這個條件,用動態規劃
狀態表示:f[i][j]
表示從S到j經過i條邊的所有方案的數量
狀態劃分:f[i + 1][j] += f[i][k], k是所有j能到的點
初始化:f[0][S] = 1
答案:f[K][T]
-
考慮x為偶數這個條件,多了一個限制,狀態就要多一維
狀態表示:f[i][j][x]
狀態劃分:1. 當j不為X時,f[i + 1][j][x] += f[i][k][x], k是所有j能到的點
2. 當j為X時,f[i + 1][j][x] += f[i][k][(x+1)%2]
初始化:f[0][S][0] = 1
答案:f[K][T][0]
程式碼
#include <iostream> #include <cstring> using namespace std; typedef long long LL; const int N = 2010, M = N * 2; LL mod = 998244353; int h[N], e[M], ne[M], idx; LL f[N][N][2]; void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx ++; } int main() { int n, m, k, S, T, X; cin >> n >> m >> k >> S >> T >> X; memset(h, -1, sizeof h); while (m -- ) { int u, v; cin >> u >> v; add(u, v); add(v, u); } f[0][S][0] = 1; for(int i = 0; i <= k; i ++ ) for(int j = 1; j <= n; j ++ ) for(int x = 0; x < 2; x ++ ) { for(int u = h[j]; ~u; u = ne[u]) { int k = e[u]; if(j != X) f[i + 1][j][x] = ((LL)f[i + 1][j][x] + f[i][k][x]) % mod; else f[i + 1][j][x] = ((LL)f[i + 1][j][x] + f[i][k][(x + 1) % 2]) % mod; } } cout << f[k][T][0]; return 0; }