这是一个区间dp问题 从题目描述我们可以知道行与行之间没有联系
于是我们可以设dp[i][j]为某一行i-j范围内所得值最大的取值方法 于是转移状态就出来了
取数变成了向这个区间加数 加的数为下次第一个取的
则有转移方程 if len==1 dp[l][r]=a[l] * 2
else dp[l][r]=max((dp[l+1][r]+a[l])2,(dp[l][r-1]+a[r])2);
答案就出来了 要用__int128 然后cincout就不行了 要用快读快输
弄了半天QAQ
#include <bits/stdc++.h> using namespace std; #define int __int128 inline int read() { int x = 0, neg = 1; char op = getchar(); while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); } while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); } return neg * x; } inline void print(int x) { if (x < 0) { putchar('-'); x = -x; } if (x >= 10) print(x / 10); putchar(x % 10 + '0'); } int n,m,a[110],ans,dp[110][110]; signed main() { // ios::sync_with_stdio(false); n=read();m=read(); for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { a[j]=read(); } for(int len=1;len<=m;++len) { for(int l=1;l+len-1<=m;++l) { int r=l+len-1; if (len==1) dp[l][r]=a[l]*2; else dp[l][r]=max((dp[l+1][r]+a[l])*2,(dp[l][r-1]+a[r])*2);///向区间两边加的数为第一个取的 } } ans+=dp[1][m]; } print(ans); return 0; }