B. Working out 四角dp
https://codeforces.com/problemset/problem/429/B
这个题目之前写过,不过好像。。忘记了,今天又没有写出来,应该之前没有想明白。。。
这个应该算一个四角dp(网上说的,感觉很符合),所以呢就是要从四个角进行dp,
就是先对四个角到对角的一个dp,然后就是枚举每一个位置,找其中最大的。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#define inf 0x3f3f3f3f
#define debug(x) cout<<"-----"<<" x = "<<x<<"-----"<<endl
using namespace std;
typedef long long ll;
const int mod = 1e8;
const int maxn = 5e5 + 10;
ll dp1[1010][1010], dp2[1010][1010], dp3[1010][1010], dp4[1010][1010];
int a[1010][1010];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d", &a[i][j]);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
dp1[i][j] = a[i][j] + max(dp1[i - 1][j], dp1[i][j - 1]);
}
}
for(int i=n;i>=1;i--)
{
for(int j=1;j<=m;j++)
{
dp2[i][j] = a[i][j] + max(dp2[i + 1][j], dp2[i][j - 1]);
}
}
for(int i=1;i<=n;i++)
{
for(int j=m;j>=1;j--)
{
dp3[i][j] = a[i][j] + max(dp3[i - 1][j], dp3[i][j + 1]);
}
}
for(int i=n;i>=1;i--)
{
for(int j=m;j>=1;j--)
{
dp4[i][j] = a[i][j] + max(dp4[i + 1][j], dp4[i][j + 1]);
}
}
ll ans = 0;
for(int i=2;i<n;i++)
{
for(int j=2;j<m;j++)
{
ans = max(ans, dp1[i - 1][j] + dp4[i + 1][j] + dp2[i][j - 1] + dp3[i][j + 1]);
ans = max(ans, dp1[i][j - 1] + dp4[i][j + 1] + dp2[i + 1][j] + dp3[i - 1][j]);
}
}
printf("%lld\n", ans);
return 0;
}