description 亏你能想的出来这么个背景……

2015年英雄联盟校园争霸赛决赛于北京时间7月31日在东北林业大学体育馆举行。经过初选的洗礼后,有来自全国各地的n支队伍汇集到本次总决赛,比赛最终要角逐出一名冠军。规则是:队伍两两之间进行比赛,失败者被淘汰,胜利者晋级,获得和其他队伍进行较量的资格,并且为本场比赛贡献一定的精彩度。比如:i和j比赛,j被淘汰,那么比赛增加a[i,j]的精彩度。作为这场比赛的赞助商东东在思考一个问题,比赛的最终精彩度怎样,到底是不是要投资呢?那么就请你帮东东预算一下比赛可能出现的最高精彩度是什么?

input

输入数据有多组。每组第一行包含一个整数n(2<=n<=10)代表参加比赛的总队伍数。接下来是一个n行n列的矩阵,a[i,j]代表i和j比赛并且j被淘汰产生的精彩度(a[i,j]<=10000)

output

输出包含一个整数,表示比赛可能出现的最大的精彩度。

sample_input

2
0 4
1 0
3
0 20 1
12 0 1
1 10 0

sample_output

4
22

比赛的时候怎么就没想到T^T根本就没有往装呀的方向上想啊 orz 其实说起来也不难啊,就是没想到啊

用二进制表示的当前状态,还存在就是1,输了没了就是0;比赛的时候纠结于怎么枚举状态并且表示出来两两比赛输了淘汰、赢了继续比赛的过程,自己写的时候也是写了一个磨磨唧唧的递归,其实远没有那么复杂,dp的过程不是按部就班的非得一一对应的递推,只要有当前状态的转移就好

/************
2016.1.3
nefu1009
840k 58ms C++ (g++ 3.4.3) 948 
************/
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,num[14][14],dp[5000];
int main()
{
   // freopen("cin.txt","r",stdin);
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                scanf("%d",&num[i][j]);
        memset(dp,0,sizeof(dp));
        for(int i=(1<<n)-1;i>=0;i--)
        {
            for(int j=0;j<n;j++)
            {
                if(i&(1<<j))
                {
                    for(int k=0;k<n;k++)
                    {
                        if(i&(1<<k)) continue;
                        if(k==j) continue;
                        dp[i]=max(dp[i],dp[i|(1<<k)]+num[j][k]);
                    }
                }
            }
        }
        int maxn=-1;
        for(int i=0;i<n;i++)
        {
            if(maxn<dp[1<<i]) maxn=dp[1<<i];
        }
        printf("%d\n",maxn);
    }
    return 0;
}