問題:N x M (≤15) 迷宮,F 起點,Y 目標點(多個),G 能量池(可充滿電,一次性),D 障礙。每步消耗 1 電量。起始電量 = 電池容量(滿電)。求能走遍所有 Y 的最小電池容量。Y+G ≤ 15。
D 格子作為節點,跑 Floyd 或多源 BFS 得到任意兩點間最短步數 dis[u][v]。節點數 ≤ 225,Floyd O(V³) 可接受,或對每個關鍵點(F, Y, G)做 BFS 更優。dp[mask][last] = 以電量 power 起出發,已訪問關鍵點集合 mask,最後停留在 last 時的剩餘電量最大值。ynum 位為 Y,後 gnum 位為 G。last 走到未訪問的 next,需 dis[last][next] ≤ 當前剩餘電量。若 next 是 G,到達後電量恢復滿電 power;否則扣除步數。mask 包含所有 Y(即 (mask & ((1<)且剩餘電量 ≥ 0。 power ∈ [0, INF],INF = N*M 足夠。檢查 ok(power),最小化 power。bool ok(int power) {
memset(dp, -1, sizeof dp);
queue> q; // {mask, last}
// 初始狀態:從 F 直接走到 Y 或 G
for (int i = 0; i < ynum; ++i)
if (power >= dis[F][Y[i]])
dp[1<= dis[F][G[i]])
dp[1<<(ynum+i)][ynum+i] = power, q.push({1<<(ynum+i), ynum+i});
while (!q.empty()) {
auto [mask, u] = q.front(); q.pop();
if ((mask & ((1< dp[nmask][v]) {
dp[nmask][v] = nrem;
q.push({nmask, v});
}
}
}
return false;
}
O((NM)²) 或 O(關鍵點數 * NM),極快。2^15 * 15 ≈ 50 萬,每狀態轉移 O(15)。log(INF) ≈ 8 次,總時間 < 1s。Y(ynum==0),答案為 0。dis = INF,二分上界設為 INF,最終無解輸出 -1(題目保證有解或輸出 -1)。