大力dp
一个正着跑,一个倒着跑,可以转换成两个正着跑
为了解决去重问题,我们规定第一条线不能越过第二条线,(没什么影响,不信画画图看看),这样就有一个显然的四维dp了,注意两个相等时要去一个
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#define maxn 101
#define int long long
#define SZJ signed
#include<time.h>
#define AK main
#define half (l+r)>>1
#define SDOI ()
using namespace std;
#define rep(i,a,b) for (int i=a;i<=b;++i)
#define dep(i,a,b) for (int i=a;i>=b;i--)
#define erpe (i,a) for (int i=head[a];i!=-1;i=e[i].next)
int n,m,dp[51][51][51][51],val[maxn][maxn];
inline int MAX(int a,int b,int c,int d) {return max(max(max(a,b),c),d);}
SZJ AK SDOI
{
cin>>n>>m;
rep(i,1,n) rep(j,1,m) cin>>val[i][j];
rep(i,1,n)
rep(j,1,m)
rep(k,1,n)
rep(l,j,m)
{
int tmp=val[i][j];
if (i!=k||j!=l) tmp+=val[k][l];
dp[i][j][k][l]=MAX(dp[i-1][j][k-1][l],dp[i-1][j][k][l-1],dp[i][j-1][k-1][l],dp[i][j-1][k][l-1]);
dp[i][j][k][l]+=tmp;
}
cout<<dp[n][m][n][m];
return 0;
}