//無優化,時間:748ms
//優化後:78ms
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int st[16][1<<16],top[16];
int mp[16][16][(1<<15)+10];
bool vis[16];
int a[16][16];
int dp[16][(1<<16)];
void int_i(int n)
{
vis[n]=1;
top[n]=0;
int total=1<<n,t1;
for(int i=0;i<total;i++)
{
t1=i&(i<<1);
if(!t1) st[n][++top[n]]=i;
}
return ;
}
int solve(int i,int j,int n)//j代表選的是哪種方案,i代表是哪一行
{
int ans=0,t=st[n][j];
while(t)
{
if(t&1)
ans+=a[i][n];
n--;
t>>=1;
}
return ans;
}
bool judge(int x,int y)
{
int t1,t2;
t1=(x&y);
t2=((x<<1)&y) || (x&(y<<1));
return !(t1||t2);
}
int main()
{
int n;
char f;
for(int i=1;i<=15;i++)
int_i(i);
while(scanf("%d",&a[1][1])!=EOF)
{
n=1;
scanf("%c",&f);
while(f!='\n')
{
scanf("%d",&a[1][++n]);
scanf("%c",&f);
}
for(int i=2;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
memset(dp,0,sizeof(dp));
for(int i=1;i<=top[n];i++)
{
dp[1][i]=solve(1,i,n);
}
for(int i=2;i<=n;i++)
{
for(int j=1;j<=top[n];j++)
{
for(int k=1;k<=top[n];k++)
{
if(judge(st[n][j],st[n][k]))
{
dp[i][j]=max(dp[i][j],dp[i-1][k]);
}
}
dp[i][j]+=solve(i,j,n);
}
}
int ans=0;
for(int i=1;i<=top[n];i++)
ans=max(dp[n][i],ans);
printf("%d\n",ans);
}
return 0;
}
//優化後:78ms
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int num=16;
int st[num][1<<num],top[num];
int a[num][num];
int dp[num][(1<<num)];
struct node
{
int v,next;
}e[num][(1<<15)+10];
int head[num][(1<<15)+10],cnt;
void addedge(int u,int v,int n)
{
e[n][++cnt].v=v;
e[n][cnt].next=head[n][u];
head[n][u]=cnt;
return ;
}
bool judge(int x,int y)
{
int t1,t2;
t1=(x&y);
t2=((x<<1)&y) || (x&(y<<1));
return !(t1||t2);
}
void int_i(int n)
{
top[n]=0;
int total=1<<n,t1;
for(int i=0;i<total;i++)
{
t1=i&(i<<1);
if(!t1) st[n][++top[n]]=i;
}
for(int i=2;i<=top[n];i++)
{
for(int j=1;j<i;j++)
{
if(judge(st[n][i],st[n][j]))
{
addedge(i,j,n);
addedge(j,i,n);
}
}
}
return ;
}
int solve(int i,int j,int n)//j代表選的是哪種方案,i代表是哪一行
{
int ans=0,t=st[n][j];
while(t)
{
if(t&1)
ans+=a[i][n];
n--;
t>>=1;
}
return ans;
}
int main()
{
int n;
char f;
for(int i=1;i<=15;i++)
int_i(i);
while(scanf("%d",&a[1][1])!=EOF)
{
n=1;
scanf("%c",&f);
while(f!='\n')
{
scanf("%d",&a[1][++n]);
scanf("%c",&f);
}
for(int i=2;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
memset(dp,0,sizeof(dp));
for(int i=1;i<=top[n];i++)
{
dp[1][i]=solve(1,i,n);
}
for(int i=2;i<=n;i++)
{
for(int j=1;j<=top[n];j++)
{
for(int k=head[n][j];k;k=e[n][k].next)
{
int v=e[n][k].v;
dp[i][j]=max(dp[i][j],dp[i-1][v]);
}
dp[i][j]+=solve(i,j,n);
}
}
int ans=0;
for(int i=1;i<=top[n];i++)
ans=max(ans,dp[n][i]);
printf("%d\n",ans);
}
return 0;
}