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\n", tmax);
38 }
39 return 0;
40 }