#include <iostream>
#include <vector>
#include <utility>
using namespace std;
// Рекурсивно генерируем все допустимые строки и считаем их.
// Сложность O(3^N)
size_t recursive_helper(vector<char>& acc, size_t pos, size_t limit)
{
size_t result = 0;
if (pos <= limit) {
acc.push_back(1);
result += recursive_helper(acc, pos + 1, limit);
acc.push_back(3);
result += recursive_helper(acc, pos + 1, limit);
if (acc.empty() || acc.back() != 1) {
acc.push_back(2);
result += recursive_helper(acc, pos + 1, limit);
};
} else {
result = 1;
}
acc.pop_back();
return result;
}
size_t task126_recursive(size_t N)
{
vector<char> acc;
acc.reserve(N);
return recursive_helper(acc, 1, N);
}
// Динамика по длине строки. Для определения какой символ мы можем сейчас поставить
// нужно знать только предыдущий символ. Чем и пользуемся.
// Сложность O(N)
size_t task126(size_t N)
{
enum
{
END_1,
END_2,
END_3
};
size_t a[] = {1, 1, 1};
size_t b[] = {0, 0, 0};
size_t* prev = a;
size_t* cur = b;
for (int i = 2; i < N+1; ++i) {
cur[END_1] = prev[END_1] + prev[END_2] + prev[END_3];
cur[END_2] = prev[END_2] + prev[END_3];
cur[END_3] = prev[END_1] + prev[END_2] + prev[END_3];
std::swap(cur,prev);
}
return prev[END_1] + prev[END_2] + prev[END_3];
}
// Можно заметить что в предыдущем алгоритме вычисления для
// cur[END_1] и cur[END_3] одинаковы. Поэтому можно их обьединить
// и за счет этого немного сьэкономить памяти
size_t task126_tricky(size_t N)
{
enum
{
END_OTHER,
END_2,
};
size_t a[] = {2, 1};
size_t b[] = {0, 0};
size_t* prev = a;
size_t* cur = b;
for (int i = 2; i < N+1; ++i) {
cur[END_OTHER] = 2 * (prev[END_OTHER] + prev[END_2]);
cur[END_2] = prev[END_OTHER] / 2 + prev[END_2];
std::swap(cur,prev);
}
return prev[END_OTHER] + prev[END_2];
}
int main() {
for (size_t i = 1; i < 31; ++i) {
auto a = task126(i);
auto b = task126_tricky(i);
auto c = a; //task126_recursive(i); //можно раскоментировать но считать будет долго
std::cout << a << " == " << b << " == " << c << " is " << ((a == b && c == b) ? "true" : "false") << std::endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8dXRpbGl0eT4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovLyDQoNC10LrRg9GA0YHQuNCy0L3QviDQs9C10L3QtdGA0LjRgNGD0LXQvCDQstGB0LUg0LTQvtC/0YPRgdGC0LjQvNGL0LUg0YHRgtGA0L7QutC4INC4INGB0YfQuNGC0LDQtdC8INC40YUuCi8vINCh0LvQvtC20L3QvtGB0YLRjCBPKDNeTikKc2l6ZV90IHJlY3Vyc2l2ZV9oZWxwZXIodmVjdG9yPGNoYXI+JiBhY2MsIHNpemVfdCBwb3MsIHNpemVfdCBsaW1pdCkKewogICAgc2l6ZV90IHJlc3VsdCA9IDA7CgogICAgaWYgKHBvcyA8PSBsaW1pdCkgewogICAgICAgIGFjYy5wdXNoX2JhY2soMSk7CiAgICAgICAgcmVzdWx0ICs9IHJlY3Vyc2l2ZV9oZWxwZXIoYWNjLCBwb3MgKyAxLCBsaW1pdCk7CiAgICAgICAgYWNjLnB1c2hfYmFjaygzKTsKICAgICAgICByZXN1bHQgKz0gcmVjdXJzaXZlX2hlbHBlcihhY2MsIHBvcyArIDEsIGxpbWl0KTsKICAgICAgICBpZiAoYWNjLmVtcHR5KCkgfHwgYWNjLmJhY2soKSAhPSAxKSB7CiAgICAgICAgICAgIGFjYy5wdXNoX2JhY2soMik7CiAgICAgICAgICAgIHJlc3VsdCArPSByZWN1cnNpdmVfaGVscGVyKGFjYywgcG9zICsgMSwgbGltaXQpOwogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdCA9IDE7CiAgICB9CgogICAgYWNjLnBvcF9iYWNrKCk7CgogICAgcmV0dXJuIHJlc3VsdDsKfQoKc2l6ZV90IHRhc2sxMjZfcmVjdXJzaXZlKHNpemVfdCBOKQp7CiAgICB2ZWN0b3I8Y2hhcj4gYWNjOwogICAgYWNjLnJlc2VydmUoTik7CiAgICByZXR1cm4gcmVjdXJzaXZlX2hlbHBlcihhY2MsIDEsIE4pOwp9CgoKLy8g0JTQuNC90LDQvNC40LrQsCDQv9C+INC00LvQuNC90LUg0YHRgtGA0L7QutC4LiDQlNC70Y8g0L7Qv9GA0LXQtNC10LvQtdC90LjRjyDQutCw0LrQvtC5INGB0LjQvNCy0L7QuyDQvNGLINC80L7QttC10Lwg0YHQtdC50YfQsNGBINC/0L7RgdGC0LDQstC40YLRjAovLyDQvdGD0LbQvdC+INC30L3QsNGC0Ywg0YLQvtC70YzQutC+INC/0YDQtdC00YvQtNGD0YnQuNC5INGB0LjQvNCy0L7Quy4g0KfQtdC8INC4INC/0L7Qu9GM0LfRg9C10LzRgdGPLgovLyDQodC70L7QttC90L7RgdGC0YwgTyhOKQpzaXplX3QgdGFzazEyNihzaXplX3QgTikKewogICAgZW51bQogICAgewogICAgICAgIEVORF8xLAogICAgICAgIEVORF8yLAogICAgICAgIEVORF8zCiAgICB9OwoKICAgIHNpemVfdCBhW10gPSB7MSwgMSwgMX07CiAgICBzaXplX3QgYltdID0gezAsIDAsIDB9OwoKICAgIHNpemVfdCogcHJldiA9IGE7CiAgICBzaXplX3QqIGN1ciA9IGI7CgogICAgZm9yIChpbnQgaSA9IDI7IGkgPCBOKzE7ICsraSkgewogICAgICAgIGN1cltFTkRfMV0gPSBwcmV2W0VORF8xXSArIHByZXZbRU5EXzJdICsgcHJldltFTkRfM107CiAgICAgICAgY3VyW0VORF8yXSA9IHByZXZbRU5EXzJdICsgcHJldltFTkRfM107CiAgICAgICAgY3VyW0VORF8zXSA9IHByZXZbRU5EXzFdICsgcHJldltFTkRfMl0gKyBwcmV2W0VORF8zXTsKICAgICAgICBzdGQ6OnN3YXAoY3VyLHByZXYpOwogICAgfQoKICAgIHJldHVybiBwcmV2W0VORF8xXSArIHByZXZbRU5EXzJdICsgcHJldltFTkRfM107Cn0KCi8vINCc0L7QttC90L4g0LfQsNC80LXRgtC40YLRjCDRh9GC0L4g0LIg0L/RgNC10LTRi9C00YPRidC10Lwg0LDQu9Cz0L7RgNC40YLQvNC1INCy0YvRh9C40YHQu9C10L3QuNGPINC00LvRjwovLyBjdXJbRU5EXzFdINC4IGN1cltFTkRfM10g0L7QtNC40L3QsNC60L7QstGLLiDQn9C+0Y3RgtC+0LzRgyDQvNC+0LbQvdC+INC40YUg0L7QsdGM0LXQtNC40L3QuNGC0YwKLy8g0Lgg0LfQsCDRgdGH0LXRgiDRjdGC0L7Qs9C+INC90LXQvNC90L7Qs9C+INGB0YzRjdC60L7QvdC+0LzQuNGC0Ywg0L/QsNC80Y/RgtC4CnNpemVfdCB0YXNrMTI2X3RyaWNreShzaXplX3QgTikKewogICAgZW51bQogICAgewogICAgICAgIEVORF9PVEhFUiwKICAgICAgICBFTkRfMiwKICAgIH07CgogICAgc2l6ZV90IGFbXSA9IHsyLCAxfTsKICAgIHNpemVfdCBiW10gPSB7MCwgMH07CgogICAgc2l6ZV90KiBwcmV2ID0gYTsKICAgIHNpemVfdCogY3VyID0gYjsKCiAgICBmb3IgKGludCBpID0gMjsgaSA8IE4rMTsgKytpKSB7CiAgICAgICAgY3VyW0VORF9PVEhFUl0gPSAyICogKHByZXZbRU5EX09USEVSXSArIHByZXZbRU5EXzJdKTsKICAgICAgICBjdXJbRU5EXzJdID0gcHJldltFTkRfT1RIRVJdIC8gMiArIHByZXZbRU5EXzJdOwogICAgICAgIHN0ZDo6c3dhcChjdXIscHJldik7CiAgICB9CgogICAgcmV0dXJuIHByZXZbRU5EX09USEVSXSArIHByZXZbRU5EXzJdOwp9CgoKaW50IG1haW4oKSB7CgogICAgZm9yIChzaXplX3QgaSA9IDE7IGkgPCAzMTsgKytpKSB7CiAgICAgICAgYXV0byBhID0gdGFzazEyNihpKTsKICAgICAgICBhdXRvIGIgPSB0YXNrMTI2X3RyaWNreShpKTsKICAgICAgICBhdXRvIGMgPSBhOyAvL3Rhc2sxMjZfcmVjdXJzaXZlKGkpOyAvL9C80L7QttC90L4g0YDQsNGB0LrQvtC80LXQvdGC0LjRgNC+0LLQsNGC0Ywg0L3QviDRgdGH0LjRgtCw0YLRjCDQsdGD0LTQtdGCINC00L7Qu9Cz0L4KICAgICAgICBzdGQ6OmNvdXQgPDwgYSA8PCAiID09ICIgPDwgYiA8PCAiID09ICIgPDwgYyA8PCAgIiBpcyAiIDw8ICgoYSA9PSBiICYmIGMgPT0gYikgPyAidHJ1ZSIgOiAiZmFsc2UiKSAgPDwgc3RkOjplbmRsOwogICAgfQogICAgcmV0dXJuIDA7Cn0=