思路
先暴力找出满足没有相邻1的的二进制状态。 预处理出第i行,状态为k是能得到的值。 最后依次递推到第n行即可。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
ll dp[20][20000];
int a[21][21];
int sta[20000];
int cnt;
ll v[20][20000];
void init()
{
int up=(1<<n);
for(int i=0;i<up;i++)
{
if((i&(i<<1))==0)
{
sta[++cnt]=i;
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
while(scanf("%d",&n)!=EOF)
{
cnt=0;
memset(v,0,sizeof(v));
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&a[i][j]);
}
}
init();
for(int i=0;i<n;i++)
{
for(int j=1;j<=cnt;j++)
{
ll tmp=0;
for(int k=0;k<n;k++)
{
if((sta[j]&(1<<k)))
{
tmp+=a[i][k];
}
}
v[i][j]=tmp;
}
}
for(int i=1;i<=cnt;i++)
{
dp[0][i]=v[0][i];
}
for(int i=1;i<n;i++)
{
for(int j=1;j<=cnt;j++)
{
for(int k=1;k<=cnt;k++)
{
if((sta[j]&sta[k])==0)
{
dp[i][j]=max(dp[i-1][k]+v[i][j],dp[i][j]);
}
}
}
}
ll ans=0;
for(int i=1;i<=cnt;i++)
{
ans=max(ans,dp[n-1][i]);
}
printf("%lld\n",ans);
}
return 0;
}