起點 0,需訪問 n 個地點(共 n+1 點),每對點有距離。求從 0 出發訪問所有點並返回 0 的最短路徑。標準旅行商問題 (TSP)。n ≤ 12。
輸入可能不連通或非直接最短,先跑 Floyd 確保 `dist[i][j]` 為最短距離。
dp[mask][last]:已訪問集合為 `mask`,當前位於 `last` 的最短路徑長度。
`mask` 包含 1..n(不含起點 0),共 2^n 狀態。
int getans(int st, int la) { // st: 剩餘未訪問集合, la: 當前位置
if (dp[st][la] != -1) return dp[st][la];
int ans = INF;
for (int i = 0; i <= n; i++) {
if ((st & (1<
初始調用:`getans((1<<(n+1))-1 - 1, 0)`?需確認狀態定義細節。代碼片段不完整,但標準 TSP DP 套路清晰。
標準 TSP DP 模板(自底向上)
dp[1<
複雜度分析
- Floyd:O(n³) = 13³ ≈ 2197
- DP 狀態:2^n × n = 4096 × 12 ≈ 5萬
- 轉移:每狀態 O(n) → 總計 O(n²2^n) ≈ 60萬
- 極快,n=12 為 TSP DP 經典適用上限
總結
本題是狀態壓縮 DP 解決 TSP的標準模板題。關鍵步驟:
- Floyd 確保距離矩陣為最短路
- 狀態定義:`dp[mask][last]`
- 轉移:枚舉前一個節點
- 答案:全訪問狀態下各終點 + 返回起點距離的最小值
記憶化搜索(自頂向下)與自底向上均可,狀態空間小時自底向上更高效。TSP 變體(如不返回起點、指定起終點、多起點等)只需微調初始化與答案計算。