AtCoder Beginner Contest 153

Updated:

AtCoder Beginner Contest 153

Source codes

Solutions

A - Serval vs Monster

Flush $(H + A - 1)/A$.

B - Common Raccoon vs Monster

Flush whether $H \leq \sum _ {i} A _ i$ or not.

C - Fennec vs Monster

Without loss of generalities, we can assume that $\{ H _ i \}$ is in the ascending order. We should attack for $H _ 0, \dotsm H _ {N - K - 1}$. The answer is the sum of them.

D - Caracal vs Monster

We can solve this by recursion or direct calculus.

Recursion

We define $f(H)$ as follows.

\[ f(H) = \begin{cases} 1 & H = 1, \\\ 1 + 2 f(H/2) & \text{otherwise}. \end{cases} \]

We flush $f(H)$.

Direct calculus

Let $high$ be the maximum bit up. For example the $high$ of $4$ is $2$. The answer is $2 ^ {high + 1} - 1$.

E - Crested Ibis vs Monster

This is solved by simple DP.

DP part

Definition

$DP[j] = $ the minimum total magic point to gain the total attack point $j$.

Here we regard $DP[H]$ is the minimum point to beat the monster whose health is $H$.

Initial state

$DP[0] = 0$, otherwise $\infty$.

Answer

$DP[H]$.

Transition

Here, we can use the same magic repeatedly as many times as we like. Therefore, we execute the transition by $j$’s ascending order.

For $i = 0, \dots, N$, for $j = 0, \dots, H - 1$, \[ DP[\min(j + A _ i, h)] \gets \min(DP[\min(j + A _ i, h)], DP[j] + B _ i). \]

F - Silver Fox vs Monster

Solution

We can solve this problem by greedy method. We regard a bomb as a range attack on $[X, X + 2D + 1)$. Without loss of generalities, we can assume that $\{ (X _ i, H _ i) \}$ is in the ascending order. For each $i$, it is the best efficient to use bombs in $[X _ i, X _ i + 2D + 1)$ the minimum times we need to beat the monster $(X _ i, H _ i)$.

Here we have to compute the attack point on the current place $X _ i$ that we have made. This is controlled by cumulated sums and the manipulation of the queue. Every time we make the bomb attack on $X _ i$ in $cnt$ times, we possess the total damage in total += A * cnt; and the end of the range of the bomb by Q.emplace(X + 2 * D + 1, A * cnt);.

  using Info = tuple<int, ll>;
  queue<Info> Q;
  ll ans{0};
  ll total{0};
  for (auto i = 0; i < N; ++i)
  {
    ll X, H;
    tie(X, H) = V[i];
    while (!Q.empty() && get<0>(Q.front()) <= X)
    {
      total -= get<1>(Q.front());
      Q.pop();
    }
    ll cnt{max(0LL, (H - total + A - 1) / A)};
    ans += cnt;
    total += A * cnt;
    Q.emplace(X + 2 * D + 1, A * cnt);
  }

Others