I've coded a program that calculates the number of partitions of n into at least two distinct parts, and is relatively quick too (about N^1.5 complexity). For input 30 000 it takes roughly 4 seconds. The memory usage rises due to its recursive nature (1Gb for 30 000). I need to calculate input that is max 300 000, but can't because of stack overflow. Increasing the stack size unfortunately throws std::bad_alloc (I have 16GB of RAM; if anyone can test that it works for 300000 it would be nice). I tried tail recursing it, but couldn't in the end because memoization would become useless.
#include <iostream>
#include <cmath>
#include <chrono>
#include <unordered_map>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/functional/hash.hpp>
std::unordered_map<std::size_t, boost::multiprecision::cpp_int> hmap;
std::size_t hashf(int a, short int b){
std::size_t seed = 0;
boost::hash_combine(seed, a);
boost::hash_combine(seed, b);
return seed;
}
boost::multiprecision::cpp_int F(int n, short int k, size_t key){
//skip branches
if((k == 1 && n > 1) || (k == 1 && n == 1))
return 1;
if(k > n || n == 0 || k == 0 || k < 0 || n < 0)
return 0;
{
auto it = hmap.find(key);
if(it != hmap.end())
return it->second;
}
return hmap[key] = F(n - k, k, hashf(n-k, k)) + F(n-k, k-1, hashf(n-k, k-1));
}
int main(){
int n;
boost::multiprecision::cpp_int res = 0;
std::cin >> n;
auto begin = std::chrono::high_resolution_clock::now();
for(short int i = 2; i <= (int)std::sqrt(2*n); i++)
res += F(n, i, hashf(n, i));
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
std::cout << res;
printf("\nTime measured: %.6f seconds.\n", elapsed.count() * 1e-9);
std::cin >> n;
return 0;
}
Edit: program is based on an answer to How many ways are there to choose non-repeating numbers that add up to N? on Mathematics SE.