洛谷 矩阵取数游戏 dp+高精度
#include <iostream>
#include <cstring>
#include <algorithm>
#include <stdio.h>
#include <cmath>
#define Mod 10000
#define MAXN 85
using namespace std;
int n,m;
int a[MAXN];
struct HP
{
int p[505],len;
HP()
{
memset(p,0,sizeof p);
len=0;
}
void print()
{
printf("%d",p[len]);
for(int i=len-1;i>0;i--)
{
if(p[i]==0)
{
printf("0000");
continue;
}
for(int k=10;k*p[i]<Mod;k=k*10)
{
printf("0");
}
printf("%d",p[i]);
}
}
}dp[MAXN][MAXN],base[MAXN],ans;
HP operator + (const HP &a,const HP &b)
{
HP c;
c.len=max(a.len,b.len);
int x=0;
for(int i=1;i<=c.len;i++)
{
c.p[i]=a.p[i]+b.p[i]+x;
x=c.p[i]/Mod;
c.p[i]%=Mod;
}
if(x>0)
c.p[++c.len]=x;
return c;
}
HP operator * (const HP &a,const int &b)
{
HP c;
c.len=a.len;
int x=0;
for(int i=1;i<=c.len;i++)
{
c.p[i]=a.p[i]*b+x;
x=c.p[i]/Mod;
c.p[i]%=Mod;
}
while(x>0)
{
c.p[++c.len]=x%Mod;
x/=Mod;
}
return c;
}
HP max(const HP &a,const HP &b)
{
if(a.len>b.len)
return a;
else if(a.len<b.len)
return b;
for(int i=a.len;i>0;i--)
{
if(a.p[i]>b.p[i])
return a;
else if(a.p[i]<b.p[i])
return b;
}
return a;
}
void BaseTwo()
{
base[0].p[1]=1;
base[0].len=1;
for(int i=1;i<=m+2;i++)
{
base[i]=base[i-1]*2;
}
}
int main()
{
cin>>n>>m;
BaseTwo();
while(n--)
{
memset(dp,0,sizeof dp);
for(int i=1;i<=m;i++)
cin>>a[i];
for(int i=1;i<=m;i++)
{
for(int j=m;j>=i;j--)
{
dp[i][j]=max(dp[i][j],dp[i-1][j]+base[m-j+i-1]*a[i-1]);
dp[i][j]=max(dp[i][j],dp[i][j+1]+base[m-j+i-1]*a[j+1]);
}
}
HP h;
for(int i=1;i<=m;i++)
{
h=max(h,dp[i][i]+base[m]*a[i]);
}
ans=ans+h;
}
ans.print();
return 0;
}