【TSP】C000_NK_字節筆試題_畢業旅行問題(二進制枚舉)

一、Problem

小明目前在做一份畢業旅行的規劃。打算從北京出發,分別去若干個城市,然後再回到北京,每個城市之間均乘坐高鐵,且每個城市只去一次。由於經費有限,希望能夠通過合理的路線安排儘可能的省一些路上的花銷。給定一組城市和每對城市之間的火車票的價錢,找到每個城市只訪問一次並返回起點的最小車費花銷。

輸入描述:

城市個數n(1<n≤20,包括北京)

城市間的車票價錢 n 行 n 列的矩陣 m[n][n]

輸出描述:

最小車費花銷 s

輸入例子1:
4
0 2 6 5
2 0 4 4
6 4 0 2
5 4 2 0

輸出例子1:
13

例子說明1:
共 4 個城市,城市 1 和城市 1 的車費爲0,城市 1 和城市 2 之間的車費爲 2,
城市 1 和城市 3 之間的車費爲 6,城市 1 和城市 4 之間的車費爲 5,依次類推。
假設任意兩個城市之間均有單程票可購買,且票價在1000元以內,無需考慮極端情況。

二、Solution

方法一:dp

  • 定義狀態
    • dp[i][j]dp[i][j] 表示從城市 ii 出發,經過城市集合 jj 中各個頂點僅一次,並回到發點 ss 的最短距離。
  • 思考狀態轉移方程
    • 如果 jj 是空集,dp[i][j] = dp[i][0] = dist[i][0] 表示從 ii 出發,經過 0 個城市,並回到出發點 s 的最短距離,也就是從城市 ii 回到出發城市 ss 的最短路距離了。
    • 否則,dp[i][k] = min(dp[i][j], dp[i][k] + dp[i][j ^ (1 <<(k-1))])j ^ (1 << (k - 1)) 表示從 ii 出發,經過城市集合 jj(不包含城市 kk),並回到出發點 ss 的最短距離。
  • 思考初始化:
    • dp[0...i][0]=dist[0...i][0]dp[0...i][0] = dist[0...i][0] 同上
  • 思考輸出dp[s][tot]dp[s][tot]tot = 1 << (n-1) - 1

java 位運算優先級殺我:(1 << (n - 1)) - 1 這樣寫是對的,但 1 << (n - 1) - 1 這樣寫是錯的,原因是左移運算符優先級比減法低。

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static class Solution {
		void init() {
			Scanner sc = new Scanner(new BufferedInputStream(System.in));
			int n = sc.nextInt(), tot = (1 << (n - 1)) - 1, g[][] = new int[n][n], dp[][] = new int[n][1<<n];
			for (int i = 0; i < n; i++)
			for (int j = 0; j < n; j++)	g[i][j] = sc.nextInt();
			for (int i = 0; i < n; i++)	dp[i][0] = g[i][0];
			
			for (int j = 1; j <= tot; j++)
            for (int i = 0; i < n; i++) {
                dp[i][j] = Integer.MAX_VALUE;
                if ((j & (1 << (i-1))) != 0)
                    continue;
                for (int k = 1; k < n; k++) {
                    if ((j & (1 << (k-1))) > 0)
                        dp[i][j] = Math.min(dp[i][j], g[i][k] + dp[k][j ^ (1 << (k-1))]);
                }
            }
			System.out.println(dp[0][tot]);
		}
	}
    public static void main(String[] args) throws IOException {  
        Solution s = new Solution();
		s.init();
    }
}

複雜度分析

  • 時間複雜度:O(n2×2n)O(n^2 × 2^n)
  • 空間複雜度:O(n2)O(n^2)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章