本题状压dp的简单应用,用0表示还没有消失或没有被使用的气体,1表示已经使用的气体。
每次枚举寻找两个气体,饭后将其中一个变成1就行。
//在这里我们直接使用一维状态的转移,这样在转移的过程中去挑选值为0的两个节点
//那么这两个节点肯定有一个留下来,我们假设删除的节点为j,那么就有
//dp[state|(1<<(j-1))] = max(dp[state] + a[i][j]);
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 20;
int dp[1<<10];
int a[maxn][maxn];

signed main()
{
    int n;
    cin>>n;
    while (n)
    {
        memset(dp, 0, sizeof(dp));
        memset(a, 0, sizeof(a));
        for (int i=1;i<=n;i++)
        {
            for (int j=1;j<=n;j++)
            {
                cin>>a[i][j];
            }
        }
        int len = (1<<n)-1;
        int ans = 0;
        for (int state=0;state<len;state++)
        {
            for (int i=1;i<=n;i++)
            {
                if (((state>>(i-1))&1)==1) continue;
                for (int j=1;j<=n;j++)
                {
                    if (((state>>(j-1))&1)==1) continue;
                    if (i==j) continue;
                    dp[state|(1<<(j-1))] = max(dp[state|(1<<(j-1))], dp[state]+a[i][j]);
                    ans = max(dp[state|(1<<(j-1))], ans);
//                     cout<<(state|(1<<(j-1)))<<' '<<dp[state|(1<<(j-1))]<<endl;
                }
            }
        }
        cout<<ans<<endl;
//         cout<<"---------"<<endl;
        cin>>n;
    }
    
    
    return 0;
}