本题状压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;
}

京公网安备 11010502036488号