题目描述
https://www.nowcoder.com/practice/3d1adf0f16474c90b27a9954b71d125d
题解
动态规划
假如有四个城市 0, 1, 2, 3,选定城市 0 为起点,那么其他三个城市用一个 3位的二进制数表示,即为 111,表示这三个城市都没去过。3位二进制数一共有 23=8 种状态。
最终花销可表示为 dp[0][111]
,假设我们先从城市 0 到城市 1,那么 dp[0][111] = cost[0][1] + dp[1][011]
,即为从城市 0 到城市 1 的花销加上从城市 1 到其他所有还没去过的城市的总花销。
注意最终要返回起点城市 0,所以 dp[i][0] = cost[i][0]
,i = 0, …, n - 1。于是二维数组 int dp[n][pow(2, n - 1)]
即记录了所有的可能性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| #include <iostream> #include <vector> #include <climits> using namespace std;
int main() { int n; cin >> n; vector<vector<int> > cost(n, vector<int>(n, 0)); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cin >> cost[i][j]; } } int all = 1 << (n - 1); vector<vector<int> > dp(n, vector<int>(all, 0)); for (int j = 0; j < all; j++) { for (int i = 0; i < n; i++) { if (j == 0) { dp[i][j] = cost[i][j]; } else { dp[i][j] = INT_MAX; for (int k = 1; k < n; k++) { int index = 1 << (k - 1); if (index & j) { int others = index ^ j; dp[i][j] = min(dp[i][j], cost[i][k] + dp[k][others]); } } } } } cout << dp[0][all - 1] << endl; return 0; }
|
参考题解