Official

C - Changing Jewels Editorial by en_translator


This problem can be solved with either recursive functions or dynamic programming. We explained recursive functions, memorized recursions, and dynamic programming in the editorial of ABC247-C, so if you don’t know these concept, we recommend you first solve the problem and read the editorials.

1. Dynamic Programming

One of the solution is dynamic programming (or DP).

Let us define \(r_1, r_2, \dots, r_N\) and \(b_1, b_2, \dots, b_N\) as follows:

  • \(r_i\): the maximum number of blue jewels of level \(1\) starting from one red jewel of level \(i\)
  • \(b_i\): the maximum number of blue jewels of level \(1\) starting from one blue jewel of level \(i\)

First, \(r_1\) and \(b_1\) are determined as follows.

  • We cannot obtain blue jewels of level \(1\) from a red jewels of level \(1\). Thus, \(r_1 = 0\).
  • We can obtain exactly one blue jewel of level \(1\) from, uh, a blue jewel of level \(1\). Thus, \(b_1 =1\).

Next, by the definition in the Problem Statement, \(r_i,b_i\) \((i \geq 2)\) can be expressed as follows.

\[ \begin{aligned} b_n &= r_{n-1} + b_{n-1} \times Y\\ r_n &= r_{n-1} + b_{n} \times X\\ \end{aligned} \]

So it is sufficient to compute \(r_n\) and \(b_n\) from \(n=1\) to \(n=N\) by the formulae above.

  • Note that you should compute \(b_n\) before computing \(r_n\), because finding \(r_n\) requires the value of \(b_n\).

An implementation follows.

#include <iostream>
using namespace std;
long long N, X, Y, r[12], b[12];
int main() {
  cin >> N >> X >> Y;
  r[1] = 0, b[1] = 1;
  for (int n = 2; n <= N; n++) {
    b[n] = r[n - 1] + b[n - 1] * Y;
    r[n] = r[n - 1] + b[n] * X;
  }
  cout << r[N] << "\n";
}

Recursive Functions

Another way is to use recursive functions.
A recursion is a description of a concept that contains the concept itself. As you can see in solution 1, the number of blue jewels of level 1 obtained from some kind of jewel depends on that from another kind, which are in a recursive relation.
A recursive function is a function that calls itself inside its body. Recursive structures like this can directly be implemented with recursive functions.
Specifically, it is enough to implement the same expression as solution 1 as a recursive function. An implementation follows.

#include <iostream>
using namespace std;

int N, X, Y;
long long calc(int level, bool is_red) {
  if (level == 1) return is_red ? 0 : 1;
  if (is_red) {
    return calc(level - 1, true) + calc(level, false) * X;
  } else {
    return calc(level - 1, true) + calc(level - 1, false) * Y;
  }
}

int main() {
  cin >> N >> X >> Y;
  cout << calc(N, true) << endl;
}

By the way, if you try to use different recursive functions for red and blue jewels, you are to use mutual recursion, which may require complex implementation. (In C++ for example, prototype declarations are required.) If you are a beginner, it is a good idea to use a single recursive function like the sample code above.

posted:
last update: