我用状态压缩做的。
一个有少于18000的合格状态,再DP 就好。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define max(a,b) a>b?a:b;
int value[23][23];
int status[18000];
int dp[22][18000];
int n,top;
int sum(int c,int sts)
{
int val=0;
int i=0;
while(sts){
if(sts&1)
val+=value[c][n-1-i];
sts=sts>>1;
i++;
}
return val;
}
void Init()
{
int i;
top=0;
int total=1<<n;
for(i=0;i<total;i++){
if(i&(i<<1)) continue;
status[top++]=i;
}
}
bool fit(int a,int b)
{
if(a&b) return false;
return true;
}
void DP()
{
int i,j,k;
memset(dp,0,sizeof(dp));
for(i=0;i<top;i++){
dp[0][i]=sum(0,status[i]);
}
for(i=1;i<n;i++){
for(j=0;j<top;j++)
for(k=0;k<top;k++){
if(fit(status[j],status[k])){
int sum1=sum(i,status[j]);
dp[i][j]=max(dp[i][j],dp[i-1][k]+sum1);
}
}
}
int ans=dp[n-1][0];
for(i=0;i<top;i++)
ans=max(ans,dp[n-1][i]);
printf("%d\n",ans);
}
int main()
{
int i,j;
while(scanf("%d",&n)!=EOF){
if(n==0) {
printf("0\n");
continue;
}
Init();
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&value[i][j]);
DP();
}
return 0;
}