LeetCode/cpp/cherry-pickup-ii.cpp

84 lines
2 KiB
C++
Raw Normal View History

#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;
}