題目描述
解題思路
題目大意:
有n*m個格子, 走過一個格子可以得到相應的分數.
A 從(1,1)沿 下 或 右 走到(n,m)
B 從(n,1)沿 上 或 右 走到(1,m)
兩人路徑有且只能有一個格子重合(重合格子的分數不算), 求兩人分數之和的最大值.
首先要保證只有一個格子重合,那麼只可能是以下兩種情況:
1) A向右走,相遇後繼續向右走,而B向上走,相遇後繼續向上走
2) A向下走,相遇後繼續向下走,而B向右走,相遇後繼續向右走
接着枚舉相遇的格子(i,j)即可,考慮四個方向的dp
dp1[i][j] := 從 (1, 1) 到 (i, j) 的最大分數
dp2[i][j] := 從 (i, j) 到 (n, m) 的最大分數
dp3[i][j] := 從 (n, 1) 到 (i, j) 的最大分數
dp4[i][j] := 從 (i, j) 到 (1, m) 的最大分數
參考代碼
#include <cstdio>
using namespace std;
const int MAX_N = 1010;
inline int max(int a, int b) {return a>b?a:b;}
int dp1[MAX_N][MAX_N], dp2[MAX_N][MAX_N], dp3[MAX_N][MAX_N], dp4[MAX_N][MAX_N];
int a[MAX_N][MAX_N];
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 = m; j >= 1; --j)
dp2[i][j] = a[i][j] + max(dp2[i][j+1], dp2[i+1][j]);
for (int i = n; i >= 1; --i)
for (int j = 1; j <= m; ++j)
dp3[i][j] = a[i][j] + max(dp3[i][j-1], dp3[i+1][j]);
for (int i = 1; i <= n; ++i)
for (int j = m; j >= 1; --j)
dp4[i][j] = a[i][j] + max(dp4[i-1][j], dp4[i][j+1]);
int ans = 0;
for (int i = 2; i < n; ++i)
for (int j = 2; j < m; ++j) {
ans = max(ans, dp1[i][j-1] + dp2[i][j+1] + dp3[i+1][j] + dp4[i-1][j]); // 對應情況1)
ans = max(ans, dp1[i-1][j] + dp2[i+1][j] + dp3[i][j-1] + dp4[i][j+1]); // 對應情況2)
}
printf("%d\n", ans);
return 0;
}