https://tools.xxooooxx.org/su/VU7TFXpms
Tag: DP
class Solution {
public:
vector<pair<int, int>> dir2 = {{1, -1}, {1, 0}, {1, 1}};
vector<pair<int, int>> dir3 = {{-1, 1}, {0, 1}, {1, 1}};
int maxCollectedFruits(vector<vector<int>>& fruits) {
int n = fruits.size();
int player1 = 0;
for (int i = 0; i < n; i++) player1 += fruits[i][i];
vector<vector<int>> player2(n, vector<int>(n, -1));
player2[0][n - 1] = fruits[0][n - 1];
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (player2[i][j] == -1) continue;
for (auto [dr, dc]: dir2) {
int x = i + dr;
int y = j + dc;
if (x < 0 || y < 0 || x >= n || y >= n) continue;
if (y <= x) continue;
player2[x][y] = max(player2[x][y], player2[i][j] + fruits[x][y]);
}
}
}
player2[n - 1][n - 1] = max(player2[n - 2][n - 1], player2[n - 2][n - 2]);
vector<vector<int>> player3(n, vector<int>(n, -1));
player3[n - 1][0] = fruits[n - 1][0];
for (int j = 0; j < n; j++) {
for (int i = j + 1; i < n; i++) {
if (player3[i][j] == -1) continue;
for (auto [dr, dc]: dir3) {
int x = i + dr;
int y = j + dc;
if (x < 0 || y < 0 || x >= n || y >= n) continue;
if (x <= y) continue;
player3[x][y] = max(player3[x][y], player3[i][j] + fruits[x][y]);
}
}
}
player3[n - 1][n - 1] = max(player3[n - 1][n - 2], player3[n - 2][n - 2]);
return player1 + player2[n - 1][n - 1] + player3[n - 1][n - 1];
}
};
本題的重點在觀察,透過觀察可以發現其實三個玩家不會互相干擾,所以我們可以將每個玩家獨立計算。
玩家1: 由於題目的 n - 1 步的限制,所以此玩家只能走對角線
玩家2 與玩家3: 可以發現他們都不會跨過對角線,因為一旦跨過對角線就將無法在限定的步數內回到 (n - 1, n - 1) 這個座標。
知道以上資訊後就可以將每個玩家透過 DP 的方式分別計算結果。