#include <cassert>
#include <vector>

namespace {

using grid_t = std::vector<std::vector<int>>;

struct solver {
    const int UNDEFINED = -1;

    solver(const grid_t &grid)
        : grid(grid), rows(static_cast<int>(grid.size())),
          cols(static_cast<int>(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<grid_t> 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<std::vector<int>> &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;
}