本题DP+高精度即可。
首先我们可以发现它的贡献只与行有关系,于是就分成n行,每行都做DP,然后将max加起来即可。(PS:用高精度实现)
上标:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mo 100000
#define ll long long
using namespace std;
int n,m,c[81][81];
struct gjd
{
int a[51],top;
}ans,f[81][81],e[81],s,d;
inline int read()
{
int x=0; char c=getchar();
while (c<'0' || c>'9') c=getchar();
while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x;
}
gjd cheng(gjd a,int b)
{
int x=0;
for (int i=1;i<=a.top;i++)
{
a.a[i]=a.a[i]*b+x;
x=a.a[i]/mo;a.a[i]%=mo;
}
while (x) a.a[++a.top]=x%mo,x/=mo;
return a;
}
gjd plus(gjd a,gjd b)
{
int x=0;
memset(d.a,0,sizeof(d.a));
d.top=max(a.top,b.top)+1;
for (int i=1;i<=d.top;i++)
{
d.a[i]=a.a[i]+b.a[i]+x;
x=d.a[i]/mo;d.a[i]%=mo;
}
while (!d.a[d.top]) d.top--;
return d;
}
gjd ma(gjd a,gjd b)
{
if (a.top>b.top) return a;
else if (a.top<b.top) return b;
for (int i=a.top;i>0;i--)
if (a.a[i]>b.a[i]) return a;
else if (a.a[i]<b.a[i]) return b;
return a;
}
int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
n=read(),m=read();
e[0].a[1]=1,e[0].top=1;
for (int i=1;i<=m;i++)
e[i]=cheng(e[i-1],2);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++) c[i][j]=read();
for (int i=1;i<=n;i++)
{
memset(f,0,sizeof(f));
f[0][m].a[1]=0,f[0][m].top=1;
for (int j=1;j<=m;j++)
{
f[j][m]=ma(f[j][m],plus(f[j-1][m],cheng(e[j],c[i][j])));
for (int k=m-1;k>=j;k--)
f[j][k]=ma(f[j][k],ma(plus(f[j-1][k],cheng(e[m-k+j],c[i][j])),plus(f[j][k+1],cheng(e[m-k+j],c[i][k+1]))));
}
for (int j=m-1;j>=0;j--)
{
f[0][j]=ma(f[0][j],plus(f[0][j+1],cheng(e[m-j],c[i][j+1])));
for (int k=1;k<=j;k++)
f[k][j]=ma(f[k][j],ma(plus(f[k-1][j],cheng(e[m-j+k],c[i][k])),plus(f[k][j+1],cheng(e[m-j+k],c[i][j+1]))));
}
memset(s.a,0,sizeof(s.a));
s.top=0;
for (int j=0;j<=m;j++)
s=ma(s,f[j][j]);
ans=plus(ans,s);
}
printf("%d",ans.a[ans.top]);
for (int i=ans.top-1;i>0;i--)
printf("%05d",ans.a[i]);
return 0;
}