#include <vector>
#include <iostream>
using namespace std;
vector<int> tri; // Запас треугольных чисел :)
long long res[2019][65];
// Рекурсивный вызов, изначально - доступны все числа (k)
long long getThree(int n, int k = tri.size()-1)
{
if (n < 0 || k < 0) return 0;
if (k == 0)
{
if (n == tri[k]) res[n][k] = 1;
if (n == 0) res[n][k] = 1;
}
else if (n == 0) res[n][k] = 1;
if (res[n][k] == -1)
{
res[n][k] = getThree(n-tri[k],k) + getThree(n,k-1);
}
return res[n][k];
}
int main(int argc, const char * argv[])
{
// Заполняем массив треугольными числами
for(int i = 1; i <= 64; ++i) tri.push_back(i*(i+1)/2);
for(int i = 0; i < 2019; ++i)
for(int j = 0; j < 65; ++j)
res[i][j] = -1;
// Приступаем...
cout << getThree(2018) << endl;
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnZlY3RvcjxpbnQ+IHRyaTsgICAgICAvLyDQl9Cw0L/QsNGBINGC0YDQtdGD0LPQvtC70YzQvdGL0YUg0YfQuNGB0LXQuyA6KQpsb25nIGxvbmcgcmVzWzIwMTldWzY1XTsKCi8vINCg0LXQutGD0YDRgdC40LLQvdGL0Lkg0LLRi9C30L7Qsiwg0LjQt9C90LDRh9Cw0LvRjNC90L4gLSDQtNC+0YHRgtGD0L/QvdGLINCy0YHQtSDRh9C40YHQu9CwIChrKQpsb25nIGxvbmcgZ2V0VGhyZWUoaW50IG4sIGludCBrID0gdHJpLnNpemUoKS0xKQp7CiAgICBpZiAobiA8IDAgfHwgayA8IDApIHJldHVybiAwOwogICAgaWYgKGsgPT0gMCkKICAgIHsKICAgICAgICBpZiAobiA9PSB0cmlba10pIHJlc1tuXVtrXSA9IDE7CiAgICAgICAgaWYgKG4gPT0gMCkgcmVzW25dW2tdID0gMTsKICAgIH0KICAgIGVsc2UgaWYgKG4gPT0gMCkgcmVzW25dW2tdID0gMTsKCiAgICBpZiAocmVzW25dW2tdID09IC0xKQogICAgewogICAgICAgIHJlc1tuXVtrXSA9IGdldFRocmVlKG4tdHJpW2tdLGspICsgZ2V0VGhyZWUobixrLTEpOwogICAgfQogICAgcmV0dXJuIHJlc1tuXVtrXTsKfQoKaW50IG1haW4oaW50IGFyZ2MsIGNvbnN0IGNoYXIgKiBhcmd2W10pCnsKICAgIC8vINCX0LDQv9C+0LvQvdGP0LXQvCDQvNCw0YHRgdC40LIg0YLRgNC10YPQs9C+0LvRjNC90YvQvNC4INGH0LjRgdC70LDQvNC4CiAgICBmb3IoaW50IGkgPSAxOyBpIDw9IDY0OyArK2kpIHRyaS5wdXNoX2JhY2soaSooaSsxKS8yKTsKICAgIGZvcihpbnQgaSA9IDA7IGkgPCAyMDE5OyArK2kpCiAgICAgICAgZm9yKGludCBqID0gMDsgaiA8IDY1OyArK2opCiAgICAgICAgICAgIHJlc1tpXVtqXSA9IC0xOwoKICAgIC8vINCf0YDQuNGB0YLRg9C/0LDQtdC8Li4uCiAgICBjb3V0IDw8IGdldFRocmVlKDIwMTgpIDw8IGVuZGw7Cn0KCg==