D - Step Up Robot 解説 by en_translator
This problem has the following property:
- Suppose that the robot is at the \(k\)-th step. Whether the robot can reach the \(l\)-th step is independent of the history of its move so far.
(For example, if the problem were like: “you have cards with non-negative integers written on them, and you may discard card \(x\) to advance \(x\) steps, but you cannot step on the step with a trap,” then the property above no longer holds, because the history affects to the upcoming moves.)
With the property above, we may design a DP (Dynamic Programming) that stores “the current step” as the state.
Define the following DP array.
- \(\operatorname{dp}[i]\coloneqq \) \(1\) if you can step on the \(i\)-th step, and \(0\) otherwise.
Then, \(\operatorname{dp}[i]\) can be computed based on the positions of traps, \(B _ i\), and whether the robot can step on the steps below, \(\operatorname{dp}[0],\operatorname{dp}[1],\ldots,\operatorname{dp}[i-1]\).
Specifically, you can compute them as follows:
\[ \operatorname{dp}[i]=\left\lbrace\begin{matrix}0&\quad&({}^\exists j.\ B _ j=i)\\\displaystyle\bigvee_j \operatorname{dp}[i-A_j]&&(\textrm{otherwise}).\end{matrix}\right. \]
In a natural language, “a step without a trap can be reached if \(A _ i\) steps below can be reached.”
Initially, you are on the \(0\)-th step, so \(\operatorname{dp}[0]=1\) 、\(\operatorname{dp}[-n]=0\ (n\gt0)\). Together with the equation above, we can find \(\operatorname{dp}\) in the increasing order of \(i\).
The following is a sample code.
#include <iostream>
#include <vector>
int main() {
using namespace std;
unsigned long N;
cin >> N;
vector<unsigned long> A(N);
for (auto &&a : A)
cin >> a;
unsigned long M;
cin >> M;
vector<unsigned long> B(M);
for (auto &&b : B)
cin >> b;
unsigned long X;
cin >> X;
// dp[i] := Is i-th step reachable?
// available[i] := Does i-th step have a trap?
vector<unsigned long> dp(X + 1), available(X + 1, 1);
for (const auto b : B)
available[b] = 0;
// 0-th step is reachable
dp[0] = 1;
for (unsigned long i{1}; i <= X; ++i)
if (!available[i])
// Step with a trap is unreachable
dp[i] = 0;
else
// Without a trap, the "or" of dp[i - a] is the answer
for (const auto a : A)
if (i >= a)
dp[i] |= dp[i - a];
cout << (dp[X] ? "Yes" : "No") << endl;
return 0;
}
投稿日時:
最終更新: