#include <iostream> #include <cstring> #include <algorithm> using namespace std; /* 1. 哪些点被用过 2. 目前停在哪个点上 2^20 * 20 => 2*10^7 f[state][j]: state表示当前哪个点被用过, j表示最后停在哪个点上 f[state][j] = f[state_k][k] + weight[k][j] state_k 表示state除掉j之后的集合, state_k要包含k 0,1,4 state = 10011 */ const int N = 20, M = 1 << 20; int n; int f[M][N], weight[N][N]; int main() { cin >> n; for(int i = 0; i < n; ++ i) for(int j = 0; j < n; ++ j) cin >> weight[i][j]; memset(f, 0x3f, sizeof(f)); f[1][0] = 0; for(int i = 0; i < 1 << n; ++ i) for(int j = 0; j < n; ++ j) if(i >> j & 1) // i的二进制表示里面第j位是不是一 for(int k = 0; k < n; ++ k) if(i - (1 << j) >> k & 1) f[i][j] = min(f[i][j], f[i - (1 << j)][k] + weight[k][j]); cout << f[(1 << n) - 1][n - 1] << endl; return 0; }