#include <iostream>
//typedef unsigned long long int ull;
int main() {
auto f = [](int n, int i, const auto& la) -> int {
auto go = [&la,n](int j, const auto& lago) -> int {
return j>3 ? 0 : la(n-j,j,la) + lago(j+1,lago);};
return n<0 ? 0 : n==0 ? 1 : go(i,go);};
int n=3000; std::cout<<"without memoization: "<<f(n, 1, f)<<'\n';
int dp[20000][3];
auto f_dp = [&dp](int n, int i, const auto& la) -> int {
auto go = [&la,n](int j, const auto& lago) -> int {
return j>3 ? 0 : la(n-j,j,la) + lago(j+1,lago);};
auto memo = [&]() mutable -> int {
if (dp[n][i]==0) dp[n][i]=go(i,go); return dp[n][i];};
return n<0 ? 0 : n==0 ? 1 : memo();};
std::cout<<"with memoization = dp: "<<f_dp(n, 1, f_dp)<<'\n';
}
I2luY2x1ZGUgPGlvc3RyZWFtPgovL3R5cGVkZWYgdW5zaWduZWQgbG9uZyBsb25nIGludCB1bGw7CiAKaW50IG1haW4oKSB7CiAgICBhdXRvIGYgPSBbXShpbnQgbiwgaW50IGksIGNvbnN0IGF1dG8mIGxhKSAtPiBpbnQgewogICAgCWF1dG8gZ28gPSBbJmxhLG5dKGludCBqLCBjb25zdCBhdXRvJiBsYWdvKSAtPiBpbnQgewogICAgCQlyZXR1cm4gaj4zID8gMCA6IGxhKG4taixqLGxhKSArIGxhZ28oaisxLGxhZ28pO307CiAgICAgICAgcmV0dXJuIG48MCA/IDAgOiBuPT0wID8gMSA6IGdvKGksZ28pO307CiAgICAKICAgIGludCBuPTMwMDA7IHN0ZDo6Y291dDw8IndpdGhvdXQgbWVtb2l6YXRpb246ICI8PGYobiwgMSwgZik8PCdcbic7CiAgICAKICAgIGludCBkcFsyMDAwMF1bM107CiAgICBhdXRvIGZfZHAgPSBbJmRwXShpbnQgbiwgaW50IGksIGNvbnN0IGF1dG8mIGxhKSAtPiBpbnQgewogICAgCWF1dG8gZ28gPSBbJmxhLG5dKGludCBqLCBjb25zdCBhdXRvJiBsYWdvKSAtPiBpbnQgewogICAgCQlyZXR1cm4gaj4zID8gMCA6IGxhKG4taixqLGxhKSArIGxhZ28oaisxLGxhZ28pO307CiAgICAJCQogICAgICAgIGF1dG8gbWVtbyA9IFsmXSgpIG11dGFibGUgLT4gaW50IHsKICAgICAgICAJaWYgKGRwW25dW2ldPT0wKSBkcFtuXVtpXT1nbyhpLGdvKTsgcmV0dXJuIGRwW25dW2ldO307CiAgICAgICAgCiAgICAgICAgcmV0dXJuIG48MCA/IDAgOiBuPT0wID8gMSA6IG1lbW8oKTt9OwogICAgCiAgICBzdGQ6OmNvdXQ8PCJ3aXRoIG1lbW9pemF0aW9uID0gZHA6ICI8PGZfZHAobiwgMSwgZl9kcCk8PCdcbic7Cn0=