【Luogu】P1005矩阵取数游戏(高精度+DP)

时间:2022-07-23 16:44:58

  题目链接

  yeah终于过辣!

  DP,f[i][j]表示每行还剩i到j这个区间的数没取的时候的值。借这个题我也把高精度的短板弥补了一下,以后高精加高精乘应该是没问题了。

  哇终于不怂高精了……

  放上代码。

  

#include<cstdio>
#include<cctype>
#include<iostream>
#include<cstring> inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct BigInteger{
int s[],len;
BigInteger(){ len=; memset(s,,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 ;
} bool operator ==(BigInteger a){
if(len!=a.len) return ;
for(int i=;i<=len;++i)
if(s[i]!=a.s[i]) return ;
return ;
} bool operator <(BigInteger a){
return (!(*this>a)&&!(*this==a));
} BigInteger operator =(char* d){
int size=strlen(d+);
(*this).len=size;
for(int i=size,tot=;tot<size;--i) (*this).s[++tot]=d[i]-'';
return *this;
} BigInteger operator =(int num){
char d[];
sprintf(d+,"%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=;
int size=std::max(len,a.len);
for(int i=,g=;g||i<=size;++i){
int now=s[i]+a.s[i]+g;
ans.s[++ans.len]=now%;
g=now/;
}
return ans;
} BigInteger in(){
char d[];
scanf("%s",d+);
*this=d;
return *this;
} BigInteger operator *(BigInteger a){
BigInteger ans;
ans.len=;
int size=len+a.len;
for(int i=;i<=len;++i)
for(register int j=;j<=a.len;++j)
ans.s[i+j-]+=s[i]*a.s[j];
for(int i=;i<size;++i){
ans.s[i+]+=ans.s[i]/;
ans.s[i]%=;
}
while(size>&&!ans.s[size]) size--;
ans.len=size;
return ans;
} }; BigInteger Pow(BigInteger a,int b){
if(b==) return a;
BigInteger ret;
ret=;
while(b){
if(b&) ret=ret*a;
a=a*a;
b>>=;
}
return ret;
} BigInteger f[][];
BigInteger d[][];
BigInteger ans;
BigInteger two;
int main(){
two=;ans=;
int n=read(),m=read();
for(int i=;i<=n;++i)
for(int j=;j<=m;++j) d[i][j]=read();
for(int T=;T<=n;++T){
memset(f,,sizeof(f));
for(int len=m;len;--len){
BigInteger Powval;Powval=Pow(two,m-len);
for(int i=;i+len-<=m;++i){
int j=i+len-;
if(j<m&&f[i][j+]+Powval*d[T][j+]>f[i][j]) f[i][j]=f[i][j+]+Powval*d[T][j+];
if(i>&&f[i-][j]+Powval*d[T][i-]>f[i][j]) f[i][j]=f[i-][j]+Powval*d[T][i-];
}
}
BigInteger Max;Max=;
BigInteger Powval=Pow(two,m);
for(int i=;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 ;
}