#include #include namespace { using grid_t = std::vector>; struct solver { const int UNDEFINED = -1; solver(const grid_t &grid) : grid(grid), rows(static_cast(grid.size())), cols(static_cast(grid[0].size())), dp(rows, std::vector(cols, std::vector(cols, UNDEFINED))) {} auto solve() -> int { return solve(0, 0, cols - 1); } private: const grid_t &grid; int rows, cols; std::vector dp; auto contains(int y, int x) const -> bool { return y >= 0 && y < rows && x >= 0 && x < cols; } auto solve(int y, int x0, int x1) -> int { // out of bounds or same if (!contains(y, x0) || !contains(y, x1) || x0 == x1) { return 0; } // is memoized if (dp[y][x0][x1] != UNDEFINED) { return dp[y][x0][x1]; } auto current = grid[y][x0] + grid[y][x1]; // last row if (y == rows - 1) { return current; } auto best = 0; for (int d0 = -1; d0 <= 1; ++d0) { for (int d1 = -1; d1 <= 1; ++d1) { best = std::max(best, current + solve(y + 1, x0 + d0, x1 + d1)); } } dp[y][x0][x1] = best; return best; } }; } // namespace class Solution { public: int cherryPickup(const std::vector> &grid) { return solver(grid).solve(); } }; int main() { Solution s; assert((s.cherryPickup(std::vector{ std::vector{3, 1, 1}, std::vector{2, 5, 1}, std::vector{1, 5, 5}, std::vector{2, 1, 1}, }) == 24)); assert((s.cherryPickup(std::vector{ std::vector{1, 0, 0, 0, 0, 0, 1}, std::vector{2, 0, 0, 0, 0, 3, 0}, std::vector{2, 0, 9, 0, 0, 0, 0}, std::vector{0, 3, 0, 5, 4, 0, 0}, std::vector{1, 0, 2, 3, 0, 0, 6}, }) == 28)); return 0; }