rt,link. 人已经懵了。
#include <iostream>
#include <ctype.h>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std ;
typedef int lint ;
const lint INF = 0x7fffffff ;
const lint MAXN = 2e1 + 5 ;
const lint MAXM = pow(2, MAXN) + 5 ;
const lint MAXS = 1e3 + 5 ;
lint s ;
lint n, m ;
lint ans = INF ;
vector<vector<lint>> dp(MAXM, vector<lint>(MAXN)) ;
vector<vector<lint>> rem(MAXN, vector<lint>(MAXN)) ;
inline void read(lint &x) {
char c ;
bool b = true ;
for (c = getchar() ; !isdigit(c) ; c = getchar())
if(c == '-') b = false ;
for (x = 0 ; isdigit(c) ; c = getchar())
x = x * 10 + c - '0' ;
if(b == false) x *= -1 ;
return ;
}
signed main ( ) {
cin >> n ;
m = pow(2, n) - 1 ;
for (lint i = 1 ; i <= n ; i ++)
for (lint j = 1 ; j <= 1 ; j ++)
read(rem[i][j]) ;
for (lint i = 1 ; i <= m ; i += 2)
for (lint j = 1 ; j <= n ; j ++)
dp[i][j] = -1 ;
dp[1][1] = 0 ;
for (lint i = 3, l = 2, p = 4 ; i <= m ; i += 2) {
if(i > p)
p = p << 1 , l ++ ;
for (lint j = 2 ; j <= l ; j ++) {
if(((i >> j - 1) & 1) == 1) {
s = (i ^ (1 << j - 1)) ; // 状态转移(求 s)
// 维护dp数组
for (int k = 1 ; k < j ; k ++)
dp[i][j] = min(dp[i][j], dp[s][k] + rem[k][j]) ;
for (int k = j + 1 ; k <= l ; k ++)
dp[i][j] = min(dp[i][j], dp[s][k] + rem[k][j]) ;
}
}
}
for (int i = 2 ; i <= n ; i ++)
ans == min(dp[s][i], ans) ;
cout << ans << '\n' ;
return 0 ;
}