Description
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
3
75 15 21
75 15 28
34 70 5
188
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=30;
int a[maxn][maxn],st[100010],dp[maxn][100010];
bool judge1(int x){
return (x&(x<<1))||(x&(x>>1));
}
int main()
{
int n,k=0;
while(scanf("%d",&n)==1){
memset(dp,0,sizeof(dp));
k=0;
memset(st,0,sizeof(st));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
for(int i=0;i<(1<<n);i++)
if(!judge1(i))
st[++k]=i;
int ans=0;
for(int i=1;i<=k;i++){
ans=0;
for(int j=0;j<n;j++)
if((1<<j)&st[i])
ans+=a[1][j+1];
dp[1][i]=ans;
}
for(int i=2;i<=n;i++){
for(int j=1;j<=k;j++){
for(int p=1;p<=k;p++){
if(!(st[j]&st[p])){
ans=0;
for(int q=0;q<n;q++)
if((1<<q)&st[j])
ans+=a[i][q+1];
dp[i][j]=max(dp[i][j],dp[i-1][p]+ans);
}
}
}
}
ans=0;
for(int i=1;i<=k;i++)
ans=max(ans,dp[n][i]);
printf("%d\n",ans);
}
return 0;
}