1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int dp[2][1<<20], st[1<<20], map[20][20]; 5 int main() 6 { 7 int i, j, k, n, h, state, tmax; 8 //用二进制标记状态(如:5(101)则符合要求) 9 for(i = state = 0; i < (1<<20); ++i) 10 if((i & (i<<1)) == 0) 11 st[state++] = i; 12 while(scanf("%d", &n) != EOF){ 13 for(i = 0; i < n; ++i) 14 for(j = 0; j < n; ++j) 15 scanf("%d", &map[i][j]); 16 for(i = 0; i < (1<<n); ++i) dp[1][i] = 0; 17 for(k = 0; k < n; ++k){ //k行 18 h = k & 1; 19 for(i = 0; i < state; ++i){ //一共(1<<n)个状态 20 if(st[i] >= (1<<n)) break; 21 int sum = 0; 22 for(j = 0; j < n; ++j) 23 if(st[i] & (1<<j)) 24 sum += map[k][j]; //每行每个状态的和 25 tmax = 0; 26 for(j = 0; j < state; ++j){ 27 if(st[j] >= (1<<n)) break; 28 if(!(st[i] & st[j])) //上一行与本行匹配的最大值 29 tmax = max(tmax, dp[1-h][st[j]]); 30 } 31 dp[h][st[i]] = tmax + sum; //每行每个状态的最优解(本行+与上一行匹配的最大值) 32 } 33 } 34 tmax = 0; 35 h = (n-1) & 1; 36 for(i = 0; i < (1<<n); ++i) tmax = max(tmax, dp[h][i]); //得到最优解 37 printf("%d ", tmax); 38 } 39 return 0; 40 }