Условие задачи
Вычислите функцию:
$$f(n)=\begin{cases} 1, \text{ если } n \leq 2 \\ f(\lfloor \frac{6\cdot n}{7} \rfloor)+f(\lfloor \frac{2\cdot n}{3} \rfloor), \text{ если } n \mod \; 2 = 1 \\ f(n-1)+f(n-3), \text{ если } n \mod \; 2 = 0 \end{cases}$$
Входные данные
Одно натуральное число $n$ $(1 \leq n \leq 10^{12})$
Выходные данные
Значение $f(n)$ , взятое по модулю $2^{32}$.
Тесты
Входные данные | Выходные данные |
---|---|
10 |
7 |
123 |
229966 |
1 |
1 |
100 |
136345 |
51 |
5092 |
Код программы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Map; import java.util.HashMap; import java.lang.Math; class Main { private static long mod = 1L << 32; public static Map<Long, Long> mp = new HashMap<Long, Long>(); public static long f(long n) { if (n <= 2) { return 1; } if (mp.containsKey(n)) { return mp.get(n); } if (n % 2 == 1) { long d = (f(6 * n / 7) % mod + f(2 * n / 3) % mod) % mod; mp.put(n, d); return mp.get(n); } long o = (f(n - 1) % mod + f(n - 3) % mod) % mod; mp.put(n, o); return mp.get(n); } public static void main (String[] args) throws java.lang.Exception { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); String[] params1 = bufferedReader.readLine().split(" "); long n; n = Long.parseLong(params1[0]); System.out.print(f(n)); } } |
Решение задачи
Решение данной задачи стоит начать с написания рекурсивной функции для вычисления функций по условию задачи. Так как рекурсия будет довольно таки сложной и много раз повторяются одни и те же результаты при вызове функции, следовательно, программа будет долгое время обрабатывать нашу задачу. То есть, к примеру, на 5 и 20 итерации, возвращаемые значения функции могут совпасть, что без оптимизации будет просчитываться еще раз, а с оптимизацией функция уже знает, чему равно значение с данными аргументами.Далее, по условию, мы пишем наконец нашу функцию:
- Если число, которое ввел пользователь, меньше либо равно двум, то наша функция возвращает значение один.
- Если есть значение с таким же ключом, то оно возвращает значение.
- Если число, которое ввел пользователь, дает остаток от деления один, то наша функция возвращает значение $f(\lfloor \frac{6\cdot n}{7} \rfloor)+f(\lfloor \frac{2\cdot n}{3} \rfloor)$.
- Во всех остальных случаях наша функция возвращает значение $f(n-1)+f(n-3)$.