LeetCode 1340. Jump Game V
原题链接
困难
作者:
JasonSun
,
2020-02-10 12:05:31
,
所有人可见
,
阅读 863
Algorithm (Dynamic Programming)
- Let $f(i)$ be the maximum number of points could be reached when starting from $i$.
- Then $$f(i)=\begin{cases}
1 & \text{if }\mathrm{size}(A)=1\\\\
1 & \text{else if }i=0\text{ and }A_{i+1}\geq A_{i}\\\\
1 & \text{else if }i=n-1\text{ and }A_{i-1}\geq A_{i}\\\\
1 & \text{else if }i\in(0,n-1)\text{ and }\min(A_{i-1},A_{i+1})\geq A_{i}\\\\
L(f(x)) & \text{else if }i=0\text{ and }A_{i+1}<A_{i}\\\\
R(f(x)) & \text{else if }i=n-1\text{ and }A_{i-1}<A_{j}\\\\
\max\{L(f(x)),R(f(x))\} & \text{else if }i\in(0,n-1)\text{ and }\min\{A_{i-1},A_{i+1})\leq A_{i}
\end{cases},$$ where
\begin{align}
L(f(x)) & :=\max_{k\in[i+1,\min{n-1,i+d}],\min A_{i:k}=A_{i}}\left{ 1+f(k)\right} ,\\
R(f(x)) & =\max_{k\in[i+1,\min{n-1,i+d}],\min A_{i:k}=A_{i}}\left{ 1+f(k)\right}
\end{align}
Code
template <class F>
struct recursive {
F f;
template <class... Ts>
decltype(auto) operator()(Ts&&... ts) const { return f(std::ref(*this), std::forward<Ts>(ts)...); }
template <class... Ts>
decltype(auto) operator()(Ts&&... ts) { return f(std::ref(*this), std::forward<Ts>(ts)...); }
};
template <class F> recursive(F) -> recursive<F>;
auto const rec = [](auto f){ return recursive{std::move(f)}; };
class Solution {
public:
int maxJumps(vector<int>& arr, int d) {
const auto n = size(arr);
const struct {
mutable std::optional<int> f[1000];
} memo;
auto f = rec([&, memo = std::ref(memo.f)](auto&& f, int i) -> int {
if (memo[i])
return *memo[i];
else
return *(memo[i] = [&](int acc = 1) {
if (size(arr) == 1)
return 1;
else if (i == 0 and arr[i + 1] >= arr[i])
return 1;
else if (i == n - 1 and arr[i - 1] >= arr[i])
return 1;
else if (0 < i and i < n - 1 and std::min(arr[i - 1], arr[i + 1]) >= arr[i])
return 1;
else
return [&](int acc = INT_MIN) {
for (int j = i + 1; j <= std::min(i + d, (int)n - 1) and arr[j] < arr[i]; ++j)
acc = std::max(acc, 1 + f(j));
for (int j = i - 1; j >= std::max(i - d, 0) and arr[j] < arr[i]; --j)
acc = std::max(acc, 1 + f(j));
return acc;
}();
}());
});
const auto solution = [&](int acc = INT_MIN) {
for (int i = 0; i < n; ++i)
acc = std::max(acc, f(i));
return acc;
}();
return solution;
}
};