
C/C++
Последовательности из 0, 1 и 2 без двух единиц и двоек подряд
Помогите пожалуйста решить задачу.

Кем гарантируется, что ответ не превосходит 32-битного максимума? Это может быть гарантировано только для n < какой-то величины, а не какими-то голословными утверждениями в постановке.
Соотношения:
Соотношения:
F(n, x) - кол-во последовательностей, начинающихся на цифру x (или оканчивающихся, неважно)
F(n) = F(n, 0) + F(n, 1) + F(n, 2)
F(1, 0) = F(1, 1) = F(1, 2) = 1
F(1) = 3
F(2) = 7
F(3) = 17
F(n, 0) = F(n-1, 0) + F(n-1, 1) + F(n-1, 2)
F(n, 1) = F(n-1, 0) + F(n-1, 2)
F(n, 2) = F(n-1, 0) + F(n-1, 1)
F(n) = F(n, 0) + F(n, 1) + F(n, 2) = 3 ∙ F(n-1, 0) + 2 ∙ F(n-1, 1) + 2 ∙ F(n-1, 2) =
= 3 ∙ F(n-1) - F(n-1, 1) - F(n-1, 2) = 3 ∙ F(n-1) - F(n-2) - F(n-2, 0) =
= 3 ∙ F(n-1) - F(n-2) - F(n-3)
Таким образом, мы можем избежать вычислений экспоненциальной сложности (попробуйте в вышеприведённой программе ввести 40 - поймёте, о чём я говорю). И конечно, никакая рекурсия здесь 100 лет не нужна, вычисляем значения снизу вверх и используем 3 последних в следующих вычислениях. #include
using namespace std;
int main() {
unsigned n;
cin >> n;
unsigned long long comb[4] = { 0, 3, 7, 17 };
for (; n > 2; n--) {
comb[0] = comb[1];
comb[1] = comb[2];
comb[2] = comb[3];
comb[3] = 3 * comb[2] - comb[1] - comb[0];
}
cout
Dimon Haos
Все работает, большое спасибо за объяснение.
обозначим F(n, x) - количество последовательностей длины n, оканчивающихся на цифру x
получаем рекуррентные соотношения:
F(1, 0) = F(1, 1) = F(1, 2) = 1
F(n, 0) = F(n-1, 0) + F(n-1, 1) + F(n-1, 2)
F(n, 1) = F(n-1, 0) + F(n-1, 2)
F(n, 2) = F(n-1, 0) + F(n-1, 1)
и требуется вывести:
F(n, 0) + F(n, 1) + F(n, 2)
получаем рекуррентные соотношения:
F(1, 0) = F(1, 1) = F(1, 2) = 1
F(n, 0) = F(n-1, 0) + F(n-1, 1) + F(n-1, 2)
F(n, 1) = F(n-1, 0) + F(n-1, 2)
F(n, 2) = F(n-1, 0) + F(n-1, 1)
и требуется вывести:
F(n, 0) + F(n, 1) + F(n, 2)
#include
unsigned int f (int n, char x) {
if (n == 1) return 1;
if (x == 1) return f(n-1, 0) + f(n-1, 2);
if (x == 2) return f(n-1, 0) + f(n-1, 1);
return f(n-1, 0) + f(n-1, 1) + f(n-1, 2);
}
using namespace std;
int main() {
int n;
cin >> n;
cout
Vip Vlip
Там и раздельное вычисление от 0, 1 и 2 тоже не нужно. Формула легко приводится к виду
F(n) = линейная комбинация F от предыдущих 3-x значений.
F(n) = линейная комбинация F от предыдущих 3-x значений.
Похожие вопросы
- Как в UTF-8 байт последовательности, где англ 1 байт, а рус 2 байта, парсер поймёт что символ русский, а не 2 англ?
- Язык С почему при обращении к отдельным символам массива/строкам, а именно str[0-1] то есть индекс -1 выводит значение 0
- Сколько раз нужно взять остаток от деления числа на кол-во единиц в его двоичном представлении, чтобы получить 0
- Определить k-ю цифру последовательности 182764125216343 … , в которой выписаны подряд кубы натуральных чисел.
- Найти решение уравнения(arccos(x-1)+x^3-4=0) на указанном диапазоне ([0.5;1.9]). используя численный метод-Метод Ньютона
- Определить встречается ли в последовательности группа букв 'one', определить последнее вхождение этой группы
- Учу с++, можете объяснить на пальцах? не понимаю работу условия в теле цикла... if ((i+1)%3 != 0)
- Дано не менее 3-х различных натуральных чисел, за которыми следует 0. Определить 3 наибольших числа в последовательности
- С++ Без трёх единиц
- Помогите найти ошибку в тесте на последовательности бит C++