题目链接:https://ac.nowcoder.com/acm/problem/16645
题目大意:

思路:我们可以看出,每行是独立的,那么对每行直接dp就可以了。
f[i][j]:取完区间[i, j]的数能够获得的最大值。枚举取左还是右就可以了。

#include <bits/stdc++.h>
#define LL long long
#define _int __int128
using namespace std;


inline __int128 read(){
    __int128 x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-'){
            f=-f;
        }
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return f*x;
}

void write(_int x){
    if(x<0){
        putchar('-'); x=-x;
    }
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}

_int a[105];
_int f[105][105], pw[105]={1};

_int DP(_int l, _int r, _int i){
    if(f[l][r]!=-1){
        return f[l][r];
    }
    if(l==r){
        return f[l][r]=a[l]*pw[i];
    }
    return f[l][r]=max(DP(l+1, r, i+1)+a[l]*pw[i], DP(l, r-1, i+1)+a[r]*pw[i]);
}

int main() {

    for(int i=1; i<105; i++){
        pw[i]=pw[i-1]*2;
    }
    _int ans=0;
    int n, m; scanf("%d%d", &n, &m);
    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            a[j]=read();
        }
        for(int j=1; j<=m; j++){
            for(int k=1; k<=m; k++){
                f[j][k]=-1;
            }
        }
        ans+=DP(1, m , 1);
    }
    write(ans);

    return 0;
}