yeah终于过辣!
DP,f[i][j]表示每行还剩i到j这个区间的数没取的时候的值。借这个题我也把高精度的短板弥补了一下,以后高精加高精乘应该是没问题了。
哇终于不怂高精了……
放上代码。
#include<cstdio> #include<cctype> #include<iostream> #include<cstring> inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } struct BigInteger{ int s[100],len; BigInteger(){ len=1; memset(s,0,sizeof(s)); } bool operator >(BigInteger a){ if(len!=a.len) return len>a.len; for(int i=len;i;--i){ if(s[i]!=a.s[i]) return s[i]>a.s[i]; } return 0; } bool operator ==(BigInteger a){ if(len!=a.len) return 0; for(int i=1;i<=len;++i) if(s[i]!=a.s[i]) return 0; return 1; } bool operator <(BigInteger a){ return (!(*this>a)&&!(*this==a)); } BigInteger operator =(char* d){ int size=strlen(d+1); (*this).len=size; for(int i=size,tot=0;tot<size;--i) (*this).s[++tot]=d[i]-'0'; return *this; } BigInteger operator =(int num){ char d[100]; sprintf(d+1,"%d",num); *this=d; return *this; } inline void out(){ for(register int i=len;i;--i) printf("%d",s[i]); } BigInteger operator +(BigInteger a){ BigInteger ans; ans.len=0; int size=std::max(len,a.len); for(int i=1,g=0;g||i<=size;++i){ int now=s[i]+a.s[i]+g; ans.s[++ans.len]=now%10; g=now/10; } return ans; } BigInteger in(){ char d[200]; scanf("%s",d+1); *this=d; return *this; } BigInteger operator *(BigInteger a){ BigInteger ans; ans.len=0; int size=len+a.len; for(int i=1;i<=len;++i) for(register int j=1;j<=a.len;++j) ans.s[i+j-1]+=s[i]*a.s[j]; for(int i=1;i<size;++i){ ans.s[i+1]+=ans.s[i]/10; ans.s[i]%=10; } while(size>1&&!ans.s[size]) size--; ans.len=size; return ans; } }; BigInteger Pow(BigInteger a,int b){ if(b==1) return a; BigInteger ret; ret=1; while(b){ if(b&1) ret=ret*a; a=a*a; b>>=1; } return ret; } BigInteger f[90][90]; BigInteger d[90][90]; BigInteger ans; BigInteger two; int main(){ two=2;ans=0; int n=read(),m=read(); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) d[i][j]=read(); for(int T=1;T<=n;++T){ memset(f,0,sizeof(f)); for(int len=m;len;--len){ BigInteger Powval;Powval=Pow(two,m-len); for(int i=1;i+len-1<=m;++i){ int j=i+len-1; if(j<m&&f[i][j+1]+Powval*d[T][j+1]>f[i][j]) f[i][j]=f[i][j+1]+Powval*d[T][j+1]; if(i>1&&f[i-1][j]+Powval*d[T][i-1]>f[i][j]) f[i][j]=f[i-1][j]+Powval*d[T][i-1]; } } BigInteger Max;Max=0; BigInteger Powval=Pow(two,m); for(int i=1;i<=m;++i) if(Max<f[i][i]+Powval*d[T][i]) Max=f[i][i]+Powval*d[T][i]; ans=ans+Max; } ans.out(); return 0; }