【题目链接】
【算法】
状压DP
先搜出一行符合的情况,然后,f[i][j]表示第i行,状态为j,能够取得的最大值,DP即可
【代码】
#include<bits/stdc++.h>
using namespace std;
#define MAXN 16
const int MAXS = 65536;
int i,j,k,n,tot,ans,val,MASK;
int a[MAXN][MAXN],f[MAXN][MAXS],ST[MAXS];
char c;
int main()
{
while (scanf("%d",&a[1][1]) != EOF)
{
n = 1;
tot = ans = 0;
memset(f,0,sizeof(f));
scanf("%c",&c);
while (c != '\n')
{
scanf("%d",&a[1][++n]);
scanf("%c",&c);
}
for (i = 2; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
scanf("%d",&a[i][j]);
}
}
MASK = (1 << n) - 1;
for (i = 0; i <= MASK; i++)
{
if (i & (i << 1)) continue;
ST[++tot] = i;
for (j = 0; j < n; j++)
{
if (i & (1 << j))
f[1][tot] += a[1][j+1];
}
}
for (i = 2; i <= n; i++)
{
for (j = 1; j <= tot; j++)
{
val = 0;
for (k = 0; k < n; k++)
{
if (ST[j] & (1 << k))
val += a[i][k+1];
}
for (k = 1; k <= tot; k++)
{
if (ST[j] & ST[k]) continue;
if (ST[j] & (ST[k] >> 1)) continue;
if (ST[j] & (ST[k] << 1)) continue;
f[i][j] = max(f[i][j],f[i-1][k] + val);
}
}
}
for (i = 1; i <= n; i++)
{
for (j = 1; j <= tot; j++)
{
ans = max(ans,f[i][j]);
}
}
printf("%d\n",ans);
scanf("%c",&c);
}
return 0;
}