#include<stdio.h>
struct big
{
int h[31];
int w;
}best[81];
int n,m,g[81][81];
void print(big a)
{
int i;
printf("%d",a.h[a.w]);
for(i=a.w-1;i>=1;i--)
{
if(a.h[i]<1000)
printf("0");
if(a.h[i]<100)
printf("0");
if(a.h[i]<10)
printf("0");
printf("%d",a.h[i]);
}
}
big clear()
{
big t;
int i;
for(i=0;i<=30;i++)
t.h[i]=0;
t.w=1;
return t;
}
big add(big a,big b)
{
int i,j;
big c=clear();
for(i=1;i<=30;i++)
c.h[i]=a.h[i]+b.h[i];
for(i=1;i<=30;i++)
{
c.h[i+1]+=c.h[i]/10000;
c.h[i]%=10000;
}
for(i=30;i>=1;i--)
if(c.h[i]!=0)
{
c.w=i;
break;
}
return c;
}
big cheng(int a,int k)
{
big b,mi;
int i,j,t;
b=clear(),mi=clear();
mi.h[1]=1;
for(i=1;i<=k;i++)
{
for(j=1;j<=mi.w;j++)
mi.h[j]*=2;
for(j=1;j<=mi.w;j++)
{
mi.h[j+1]+=mi.h[j]/10000;
mi.h[j]%=10000;
}
if(mi.h[mi.w+1]!=0)
mi.w++;
}
for(i=1;i<=mi.w;i++)
b.h[i]=mi.h[i]*=a;
for(i=1;i<=mi.w;i++)
{
b.h[i+1]+=b.h[i]/10000;
b.h[i]%=10000;
}
if(b.h[mi.w+1]!=0)
b.w=mi.w+1;
else
b.w=mi.w;
return b;
}
int compare(big a,big b)
{
int i;
if(a.w>b.w)
return 1;
else if(a.w<b.w)
return 0;
for(i=a.w;i>=1;i--)
{
if(a.h[i]>b.h[i])
return 1;
else if(a.h[i]<b.h[i])
return 0;
}
return 1;
}
big dp(int id)
{
int i,j,k,temp[81];
big max[81][81],a,b;
for(i=1;i<=m;i++)
temp[i]=g[id][i];
for(i=1;i<=80;i++)
for(j=1;j<=80;j++)
max[i][j]=clear();
for(i=1;i<=m;i++)
max[i][1]=cheng(temp[i],m);
for(j=2;j<=m;j++)
{
for(i=1;i<=m-j+1;i++)
{
max[i][j]=cheng(temp[i],m-j+1);
max[i][j]=add(max[i][j],max[i+1][j-1]);
a=cheng(temp[i+j-1],m-j+1);
a=add(a,max[i][j-1]);
if(compare(a,max[i][j]))
{
for(k=1;k<=30;k++)
max[i][j].h[k]=a.h[k];
max[i][j].w=a.w;
}
}
}
return max[1][m];
}
int main()
{
int i,j;
big a;
scanf("%d %d\n",&n,&m);
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
scanf("%d ",&g[i][j]);
scanf("\n");
}
for(i=1;i<=n;i++)
best[i]=clear();
a=clear();
for(i=1;i<=n;i++)
best[i]=dp(i);
for(i=1;i<=n;i++)
a=add(a,best[i]);
print(a);
printf("\n");
}
还有就是每个数的初值,没必要把每一位都设成0吧。把个位设成0就行,因为还存着长度呢,长度为1的话别的数没用的。不过你是图高加方便是吧,你的高加是每一位的加,我觉得还是添0然后加快写。毕竟从初始化到高加的过程都少不少运算。
这个每行可以单独算。所以你的best[i]可以改为best就行,g[i][j]改成g[i]就行。算完一行加一行的数。
我还用了个小优化,就是用到2的50次方一下的数的时候,用int64存,乘的时候就不用高成单了,直接乘即可。加到max[][]里的时候相当于高加单。不过这个优化不是决定性的。把我从两点超时拯救的决定性的还是那个100位变10位....
耐心的慢慢优化吧...一点一点来。我也忙活了半天