Working out
Working out
https://ac.nowcoder.com/acm/problem/110489
思路:我们可以直接从4个顶点暴力DP。
DP[1/2/3/4][i][j]表示从某个顶点到(i,j)的最大权值和。
求出之后,我们可以直接枚举相遇点
计算到达最终点的权值和最大即可。
参考代码如下:
#include <cstdio> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 1e3 + 10; const int mod = 1e9 + 7; int dp[5][maxn][maxn]; int n, m, ans, a[maxn][maxn]; int main() { 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) dp[1][i][j] = max(dp[1][i - 1][j], dp[1][i][j - 1]) + a[i][j]; for (int i = 1; i <= n; ++i) for (int j = m; j >= 1; --j) dp[2][i][j] = max(dp[2][i - 1][j], dp[2][i][j + 1]) + a[i][j]; for (int i = n; i >= 1; --i) for (int j = m; j >= 1; --j) dp[3][i][j] = max(dp[3][i + 1][j], dp[3][i][j + 1]) + a[i][j]; for (int i = n; i >= 1; --i) for (int j = 1; j <= m; ++j) dp[4][i][j] = max(dp[4][i + 1][j], dp[4][i][j - 1]) + a[i][j]; for (int i = 2; i < n; ++i) for (int j = 2; j < m; ++j) ans = max (ans, dp[1][i - 1][j] + dp[3][i + 1][j] + dp[2][i][j + 1] + dp[4][i][j - 1]), ans = max (ans, dp[1][i][j - 1] + dp[3][i][j + 1] + dp[2][i - 1][j] + dp[4][i + 1][j]); printf ("%d\n", ans); }