#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=25;
int n, num[maxn][maxn], sum[maxn][maxn], dp[maxn][maxn];
int state[maxn], cnt=0;
void init(){
for(int i=1; i<(1<<n); i++)
{
if((i&(i<<1))==0)//判断取的两个数是否相邻的方法
{
state[++cnt]=i;//保存状态
for(int j=1; j<=n; j++)
for(int k=0; k<n; k++)
if((i>>k)&1) sum[j][cnt]+=num[j][k+1];
}
}
}
void solve(){
for(int j=1; j<=cnt; j++)
dp[1][j]=sum[1][j];
for(int i=2; i<=n; i++)
{
for(int j=1; j<=cnt; j++)
for(int k=1; k<=cnt; k++)
if((state[j]&state[k])==0)
dp[i][j]=max(dp[i][j], dp[i-1][k] + sum[i][j]);//第i层j状态的状态转移方程
}
int mx=0;
for(int i=1; i<=cnt; i++)
mx=max(mx, dp[n][i]);
printf("%d\n", mx);
return ;
}
int main(){
scanf("%d", &n);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d", &num[i][j]);
init();
solve();
return 0;
}
方格取数(状压DP)
最新推荐文章于 2021-12-12 19:16:30 发布