Problem:
Problem C:
Pollock's conjecture
The
n
th triangular number is
defined as
the sum of the first
n
positive integers.
The
n
th tetrahedral number is
defined as
the sum of the first
n
triangular numbers.
It is easy to show that
the
n
th tetrahedral number is equal to
n
(
n
+1)(
n
+2) ⁄ 6.
For example,
the 5th tetrahedral number is
1+(1+2)+(1+2+3)+(1+2+3+4)+(1+2+3+4+5)
= 5×6×7 ⁄ 6
= 35.
The first 5 triangular numbers
1, 3, 6, 10, 15
The first 5 tetrahedral numbers
1, 4, 10, 20, 35
In 1850,
Sir Frederick Pollock, 1st Baronet,
who was not a professional mathematician
but a British lawyer and Tory (currently known as Conservative) politician,
conjectured
that every positive integer can be represented
as the sum of at most five tetrahedral numbers.
Here,
a tetrahedral number may occur in the sum more than once
and,
in such a case, each occurrence is counted separately.
The conjecture has been open for more than one and a half century.
Your mission is to write a program
to verify Pollock's conjecture for individual integers.
Your program should make a calculation of
the least number of tetrahedral numbers
to represent each input integer as their sum.
In addition,
for some unknown reason,
your program should make a similar calculation
with only odd tetrahedral numbers available.
For example,
one can represent 40 as the sum of 2 tetrahedral numbers,
4×5×6 ⁄ 6 + 4×5×6 ⁄ 6,
but 40 itself is not a tetrahedral number.
One can represent 40 as the sum of 6 odd tetrahedral numbers,
5×6×7 ⁄ 6 + 1×2×3 ⁄ 6 + 1×2×3 ⁄ 6 + 1×2×3 ⁄ 6 + 1×2×3 ⁄ 6 + 1×2×3 ⁄ 6,
but cannot represent as the sum of fewer odd tetrahedral numbers.
Thus, your program should report 2 and 6 if 40 is given.
Input
The input is a sequence of lines each of which contains a single positive integer less than 10
6
.
The end of the input is indicated by a line containing a single zero.
Output
For each input positive integer,
output a line containing two integers separated by a space.
The first integer should be
the least number of tetrahedral numbers
to represent the input integer as their sum.
The second integer should be
the least number of odd tetrahedral numbers
to represent the input integer as their sum.
No extra characters should appear in the output.
Sample Input
40
14
5
165
120
103
106
139
0
Output for the Sample Input
2 6
2 14
2 5
1 1
1 18
5 35
4 4
3 37

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#pragma GCC target("avx2")
#ifndef LOCAL
#pragma GCC optimize("O3")
#endif
#pragma GCC optimize("unroll-loops")

#ifdef ONLINE_JUDGE
#include <boost/multiprecision/cpp_int.hpp>
#include <atcoder/all>
#endif
#ifdef LOCAL
#define GLIBCXX_DEBUG
#define endl endl<<flush
#else
#define endl "\n"
#endif
using namespace std;using ll=long long;using ull=unsigned long long;using dl=long double;
#define rep(i,n) for(ll i=0; i<(n); i++)
#define rrep(i,n) for(ll i=1; i<=(n); i++)
#define drep(i,n) for(ll i=(n)-1; i>=0; i--)
#define xfor(i,s,e) for(ll i=(s); i<(e); i++)
#define rxfor(i,s,e) for(ll i=(s); i<=(e); i++)
#define dfor(i,s,e) for(ll i=(s)-1; i>=(e); i--)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define chmax(x,y) x = max(x,y)
#define chmin(x,y) x = min(x,y)
#define popcnt(s) ll(__popcount<ull>(uint64_t(s)))
template<typename T>istream&operator>>(istream&is,pair<T,T>&v){is>>v.first>>v.second;return is;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(auto&in:v)is>>in;return is;}
template<typename T, typename U>ostream&operator<<(ostream&os,pair<T,U>&v){os<<v.first<<" "<<v.second;return os;}
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){for(auto&in:v)os<<in<<' ';return os;}
ll modpow(ll a, ll b, ll mod) {ll res = 1;while (b > 0) {if (b & 1) res = (res * a) % mod;a = (a * a) % mod;b >>= 1;}return res;}
ll powl(ll a, ll b) {ll res = 1;while (b > 0) {if (b & 1) res = (res * a);a = (a * a);b >>= 1;}return res;}
#define pow2(a) (a)*(a)
/*MOD MUST BE A PRIME NUMBER!!*/ll moddiv(const ll a, const ll b, const ll mod) {ll modinv = modpow(b, mod-2, mod);return (a * modinv) % mod;}
constexpr ll INF = 2e15;
ll nC2(const ll i){return i>2?i*(i-1)/2:0;}ll nC3(const ll i){return i>3?i*(i-1)*(i-2)/6:0;}ll nC4(const ll i){return i>4?i*(i-1)*(i-2)*(i-3)/24:0;}ll nC5(const ll i){return i>5?i*(i-1)*(i-2)*(i-3)*(i-4)/120:0;}ll nC6(const ll i){return i>6?i*(i-1)*(i-2)*(i-3)*(i-4)*(i-5)/720:0;}
void warshall_floyd(vector<vector<ll>>& dist) {const ull n = dist.size();rep(k, n) rep(i, n) rep(j, n) {dist[i][j] = min(dist[i][j],dist[i][k] + dist[k][j]);}}
#define YES {cout<<"Yes\n";return;}
#define NO {cout<<"No\n";return;}
#define yn YES else NO
#ifdef ONLINE_JUDGE
using lll = boost::multiprecision::cpp_int;
//using lll = boost::multiprecision::int128_t;
using namespace atcoder;
//using mint = modint1000000007;
using mint = modint998244353;
//using mint = modint; // custom mod
//atcoder::modint::set_mod(m);
// DSU == UnionFind
#endif
#define vc vector
using P = pair<ll, ll>;using vl = vc<ll>;using vb=vc<bool>;using vs=vc<string>;using vvl=vc<vl>;using vp=vc<P>;
template<typename T>void cs(vector<T>&v){xfor(i,1,v.size())v[i]+=v[i-1];}

vl dx = {-1, 1, 0, 0, -1, 1, -1, 1};
vl dy = {0, 0, 1, -1, -1, -1, 1, 1};

constexpr ll mod = 998244353;

void solve() {
    vl pollocs(200);
    rrep(i, pollocs.size()) {
        pollocs[i-1] = i*(i+1)*(i+2)/6;
    }

    vl min_sums(1'000'000, INF), min_sums_odd(1'000'000, INF);
    min_sums[0] = min_sums_odd[0] = 0;

    for (ll v : pollocs) {
        if (v & 1) {
            // odds
            xfor(i, v, min_sums_odd.size()) {
                chmin(min_sums_odd[i], min_sums_odd[i-v]+1);
            }
        }

        // all
        xfor(i, v, min_sums.size()) {
            chmin(min_sums[i], min_sums[i-v]+1);
        }
    }

    ll i;
    while (true) {
        cin >> i;
        if (i == 0) break;
        cout << min_sums[i] << " " << min_sums_odd[i] << endl;
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cout << fixed << setprecision(50);

    ll n = 1;
    //cin >> n;
    while (n--) {
        solve();
    }
}
accuracy: 1
time_ms: 40
memory_kb: 19064
final_rank: 16

code_snippet: #include <climits>
#include <iostream>
#include <vector>

using namespace std;

int main(){
    vector<int> T;
    T.push_back(0);
    vector<int> T_odd;
    T_odd.push_back(0);
    int t=1;
    int n=1;
    while(1){
        t = n * (n+1) * (n+2) / 6;
        if (t > 1000000) break;
        T.push_back(t);
        n++;
        if (t%2 == 0) continue;
        T_odd.push_back(t);
    }

    int T_NUM_MAX = T.size() - 1;
    vector<int> dp(1000001, INT_MAX);
    dp[0] = 0;

    // for (int v=1; v<5; v++){
    for (int v=1; v<=dp.size(); v++){
        for (int n=1; n<=T_NUM_MAX; n++){
            if (v-T[n] >= 0) dp[v] = min(dp[v-T[n]]+1, dp[v]);
        }
    }


    int T_ODD_NUM_MAX = T_odd.size() - 1;
    vector<int> dp_odd(1000001, INT_MAX);
    dp_odd[0] = 0;

    // for (int v=1; v<5; v++){
    for (int v=1; v<=dp_odd.size(); v++){
        for (int n=1; n<=T_ODD_NUM_MAX; n++){
            if (v-T_odd[n] >= 0) dp_odd[v] = min(dp_odd[v-T_odd[n]]+1, dp_odd[v]);
        }
    }



    int inputN;
    while(1){
        cin >> inputN;
        if (inputN == 0) break;
        cout << dp[inputN] << " " << dp_odd[inputN] << endl;
        // cout << dp[inputN][T_NUM_MAX] << " " << dp_odd[inputN][T_ODD_NUM_MAX] << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 10620
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, a, n) for (int i = a; i < n; ++i)
#define rrep(i, a, n) for (int i = n - 1; i >= a; --i)
using ll = long long;
using ld = long double;
using pl = pair<ll, ll>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vp = vector<pl>;
using vvp = vector<vp>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vs = vector<string>;
using vc = vector<char>;
using vvc = vector<vc>;
using vd = vector<ld>;
using vvd = vector<vd>;
const int mod = 1000000007;
const ll hashh = 2147483647;

int main()
{
    ll n = 1;
    vl k;
    vl ki;
    while ((n * (n + 1) * (n + 2)) / 6 < 2000000)
    {
        k.push_back((n * (n + 1) * (n + 2)) / 6);
        n++;
        if (k.back() % 2 == 1)
        {
            ki.push_back(k.back());
        }
    }
    vl dp1(1000010), dp2(1000010);
    vb flag1(1000010), flag2(1000010);
    queue<ll> q;
    rep(i, 0, k.size())
    {
        if (k[i] > 1000010)
            break;
        if (!flag1[k[i]])
        {
            dp1[k[i]] = 1;
            flag1[k[i]] = true;
            q.push(k[i]);
        }
    }
    while (!q.empty())
    {
        ll p = q.front();
        q.pop();
        rep(i, 0, k.size())
        {
            if (k[i] + p > 1000010)
            {
                break;
            }
            if (!flag1[k[i] + p])
            {
                dp1[k[i] + p] = dp1[p] + 1;
                flag1[k[i] + p] = true;
                q.push(k[i] + p);
            }
        }
    }

    rep(i, 0, ki.size())
    {
        if (ki[i] > 1000010)
            break;
        if (!flag2[ki[i]])
        {
            dp2[ki[i]] = 1;
            flag2[ki[i]] = true;
            q.push(ki[i]);
        }
    }
    while (!q.empty())
    {
        ll p = q.front();
        q.pop();
        rep(i, 0, ki.size())
        {
            if (ki[i] + p > 1000010)
            {
                break;
            }
            if (!flag2[ki[i] + p])
            {
                dp2[ki[i] + p] = dp2[p] + 1;
                flag2[ki[i] + p] = true;
                q.push(ki[i] + p);
            }
        }
    }
    while (1)
    {
        ll a;
        cin >> a;
        if (a == 0)
            break;
        cout << dp1[a] << ' ' << dp2[a] << endl;
    }
}
accuracy: 1
time_ms: 250
memory_kb: 25940
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define oke cout << "Yes" << '\n';
#define dame cout << "No" << '\n';
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
using Hai2 = vector<vector<ll>>;
using HaiB = vector<vector<bool>>;
using Hai3 = vector<vector<vector<ll>>>;

int main() {
	cout << fixed << setprecision(15);
    vector<ll>A(183);
    rep(i,183){
        A[i]=i*(i+1)*(i+2)/6;
    }
    vector<ll>DP(1e6,1e9);
    vector<ll>DPV(1e6,1e9);
    DP[0] = 0;
    DP[1] = 1;

    DPV[0] = 0;
    DPV[1] = 1;
    
    for(int i = 2; i < 1000000; i++){
        for(int k = 1; A[k] <= i; k++){
            DP[i] = min(DP[i], DP[i-A[k]]+1);
            if(A[k]%2 == 1){
                DPV[i] = min(DPV[i],DPV[i-A[k]]+1);
            }
        }
    }

    while(true){
        ll N;
        cin>>N;
        if(N==0){
            break;
        }
        cout<<DP[N]<<" "<<DPV[N]<<"\n";
    }
}
accuracy: 1
time_ms: 190
memory_kb: 18776
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
int a[205],dp[1000005],f[1000005];
int main(){
	int i,j;
	for(i=1;i<=200;i++){
		a[i]=i*(i+1)*(i+2)/6;
	}
	int n;
	cin>>n;
	while(n>0){
		memset(dp,0x3f3f3f,sizeof(dp));
		memset(f,0x3f3f3f,sizeof(f));
		dp[0]=0;
		f[0]=0;
		for(i=1;i<=200;i++){
			for(j=a[i];j<=n;j++){
				dp[j]=min(dp[j],dp[j-a[i]]+1);
			}
		}
		for(i=1;i<=200;i++){
			if(a[i]%2){
				for(j=a[i];j<=n;j++){
					f[j]=min(f[j],f[j-a[i]]+1);
				}
			}
		}
		cout<<dp[n]<<" "<<f[n]<<endl;
		cin>>n;
	}
}
accuracy: 1
time_ms: 3790
memory_kb: 11244
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;
using ll = long long;
using ld = long double;
using P = pair<ll,ll>;
using Board = vector<string>;
// using mint = modint998244353;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using vp = vector<P>;
using vvp = vector<vector<P>>;
using vb = vector<bool>;
using vvb = vector<vector<bool>>;
using vs = vector<string>;
using sl = set<ll>;
using Graph = vector<vector<ll>>;
using pq = priority_queue<ll>;
using pqg = priority_queue<ll, vector<ll>, greater<ll>>;
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define nall(a) a.begin(), a.end()
const ll INF = 1LL << 60;

int main(){
    vl pollock;
    ll cnt = 1;
    while (true) {
        ll tmp = (cnt*(cnt+1)*(cnt+2))/6;
        if (tmp > 1000000) break;
        pollock.push_back(tmp);
        cnt++;
    }
    vl dp(1000010,INF), odd_dp(1000010,INF);
    dp[0] = odd_dp[0] = 0;
    rep(i,1000009)rep(j,(ll)pollock.size()) {
        if (pollock[j] > i) break;
        dp[i] = min(dp[i], dp[i-pollock[j]]+1);
        if (pollock[j]%2) odd_dp[i] = min(odd_dp[i], odd_dp[i-pollock[j]]+1);
    }
    ll q;
    while (cin >> q, q) {
        cout << dp[q] << " " << odd_dp[q] << endl;
    }
}
accuracy: 1
time_ms: 150
memory_kb: 18560
final_rank: 15

code_snippet: #include <bits/stdc++.h>

using namespace std;

int main() {
  vector<int> N(200,0);
  vector<int> N_odd;
  for (int i = 1; i < 200; ++i) {
    int curr = i * (i + 1) * (i + 2) / 6;
    N[i] = curr;
    if (curr % 2) N_odd.push_back(curr);
  }

  vector<int> dp1(pow(10,6) + 1, INT_MAX);
  dp1[0] = 0;
  for (int i = 0; i < pow(10,6) + 1; ++i) {
    for (int n: N) {
      if (i + n < pow(10, 6) + 1) dp1[i + n] = min(dp1[i + n], dp1[i] + 1);
    }
  }

  vector<int> dp2(pow(10,6) + 1, INT_MAX);
  dp2[0] = 0;
  for (int i = 0; i < pow(10,6) + 1; ++i) {
    for (int n: N_odd) {
      if (i + n < pow(10, 6) + 1) dp2[i + n] = min(dp2[i + n], dp2[i] + 1);
    }
  }

  vector<pair<int, int>> res_list;
  while (true) {
    int target; cin >> target;
    if (target == 0) break;
    res_list.push_back({dp1[target], dp2[target]});
  }
  for (auto res: res_list) cout << res.first << " " << res.second << endl;
  return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 10652
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // 入力を一旦読み溜め（0で終了）
    vector<int> qs;
    while (true) {
        int x;
        if (!(cin >> x)) return 0;
        if (x == 0) break;
        qs.push_back(x);
    }
    if (qs.empty()) return 0;

    int MAXN = *max_element(qs.begin(), qs.end());

    // 正四面体数の列挙（<= MAXN）
    vector<int> tet, tet_odd;
    for (long long k = 1;; k++) {
        long long t = k * (k + 1) * (k + 2) / 6;
        if (t > MAXN) break;
        tet.push_back((int)t);
        if (t % 2 == 1) tet_odd.push_back((int)t);
    }

    const int INF = 1e9;

    // 通常版 DP（最小個数）
    vector<int> dp(MAXN + 1, INF);
    dp[0] = 0;
    for (int c : tet) {
        for (int v = c; v <= MAXN; v++) {
            if (dp[v - c] + 1 < dp[v]) dp[v] = dp[v - c] + 1;
        }
    }

    // 奇数正四面体数のみ DP
    vector<int> dp_odd(MAXN + 1, INF);
    dp_odd[0] = 0;
    for (int c : tet_odd) {
        for (int v = c; v <= MAXN; v++) {
            if (dp_odd[v - c] + 1 < dp_odd[v]) dp_odd[v] = dp_odd[v - c] + 1;
        }
    }

    // 出力
    for (int x : qs) {
        cout << dp[x] << ' ' << dp_odd[x] << '\n';
    }
    return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 10484
final_rank: 2

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <limits>
#define sz(x) int((x).size())
#define phb push_back
using namespace std;

const int kMax = 1000000;
const int kInf = numeric_limits< int >::max() / 2;

int N;
vector< int > f1, f2;

void prep();
void solve();

int main() {
  prep();
  while (cin >> N, N)
    cout << f1[N] << " " << f2[N] << "\n";

  return 0;
}

void prep() {
  vector< int > s;

  s.phb(0);
  while (s.back() < kMax)
    s.phb(sz(s) * (sz(s) + 1) * (sz(s) + 2) / 6);

  f1.resize(kMax + 1, kInf);
  f2.resize(kMax + 1, kInf);

  f1[0] = f2[0] = 0;
  for (int i = 0; i < sz(f1); ++i)
    for (int j = 1; j < sz(s) && i + s[j] <= kMax; ++j) {
      f1[i + s[j]] = min(f1[i + s[j]], f1[i] + 1);
      if (s[j] % 2)  f2[i + s[j]] = min(f2[i + s[j]], f2[i] + 1);
    }
}
accuracy: 1
time_ms: 170
memory_kb: 10764
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <climits>

using namespace std;

int main() {

  vector<int> tetra;
  vector<int> tetra_odd;
  for (int i = 1; i < 200; ++i) {
    tetra.push_back(i * (i + 1) * (i + 2) / 6);
    if ((i * (i + 1) * (i + 2) / 6) % 2 == 1) tetra_odd.push_back(i * (i + 1) * (i + 2) / 6);
  }

  vector<int> dp1(1000001, INT_MAX);
  dp1[0] = 0;
  for (int i = 1; i < dp1.size(); ++i) {
    for (int j = 0; j < tetra.size(); ++j) {
      if (tetra[j] > i) continue;
      dp1[i] = min(dp1[i], dp1[i - tetra[j]] + 1);
    }
  }
  vector<int> dp2(1000001, INT_MAX);
  dp2[0] = 0;
  for (int i = 1; i < dp2.size(); ++i) {
    for (int j = 0; j < tetra_odd.size(); ++j) {
      if (tetra_odd[j] > i) continue;
      dp2[i] = min(dp2[i], dp2[i - tetra_odd[j]] + 1);
    }
  }
  
  vector<pair<int,int>> res_list;
  while (true) {
    int N; cin >> N;
    if (N == 0) break;
    res_list.push_back({dp1[N], dp2[N]});
  }
  for (auto p: res_list) {
    cout << p.first << " " << p.second << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 10712
final_rank: 11

code_snippet: #include<iostream>
#include<vector>
using namespace std;

int main(){
  int i,j,k;
  int x,y;
  int inf = 1 << 10;
  int m[200]={};
  int memo[1000005]={};
  int memo2[1000005]={};
  vector <int>  odd;
  fill(memo,memo+1000005,inf);
  fill(memo2,memo2+1000005,inf);
  for(i=1;i<201;i++) {
    m[i-1]=i*(i+1)*(i+2)/6;
    if(m[i-1]%2==1) odd.push_back(m[i-1]);
  }
  memo[0]=0;
  for(i=0;i<200;i++) {
    for(j=m[i];j<1000005;j++){
      memo[j]=min(memo[j],memo[j-m[i]]+1);
    }
  }
  memo2[0]=0;
  for(i=0;i<odd.size();i++) {
    for(j=odd[i];j<1000005;j++){
      memo2[j]=min(memo2[j],memo2[j-odd[i]]+1);
    }
  }
  int n;
  cin >> n;
  while(n!=0){
    cout << memo[n] << " " <<  memo2[n] << endl;
    cin >> n;
  }
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 11260
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
int INF=1001001;

int main() {
    vector<int> tetra, odd;
    int x=1;
    while(x*(x+1)*(x+2)/6 <1000000){
        tetra.push_back(x*(x+1)*(x+2)/6);
        if(x*(x+1)*(x+2)/6 %2){
            odd.push_back(x*(x+1)*(x+2)/6);
        }
        x++;
    }
    int ts=tetra.size(), os=odd.size();
    vector<int> tdp(1000000,INF), odp(1000000,INF);
    tdp[0]=0, odp[0]=0;

    for(int i=1; i<1000000; i++){
        for(int j=0; j<ts; j++){
            if(i<tetra[j]) break;
            tdp[i]=min(tdp[i],tdp[i-tetra[j]]+1);
        }
    }

    for(int i=1; i<1000000; i++){
        for(int j=0; j<os; j++){
            if(i<odd[j]) break;
            odp[i]=min(odp[i],odp[i-odd[j]]+1);
        }
    }

    int N;
    while(cin >> N){
        if(N==0){
            break;
        }
        cout << tdp[N] << ' ' << odp[N] << '\n';
    }
    
}
accuracy: 1
time_ms: 130
memory_kb: 10632
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int inf = (1 << 30);
const int m = 1000100;

int main() {
    vector<int> dp(m, inf), o_dp(m, inf);
    dp[0] = 0;
    o_dp[0] = 0;
    int i = 1;
    while(true){
        int num = i * (i+1) * (i+2) / 6;
        if(num >= m) break;
        for(int j = num; j < m; j++){
            dp[j] = min(dp[j], dp[j-num]+1);
            if(num % 2 == 1){
                o_dp[j] = min(o_dp[j], o_dp[j-num]+1);
            }
        }
        i++;
    }
    
    int x;
    while(true){
        cin >> x;
        if(x == 0){
            break;
        }
        cout << dp[x] << " " << o_dp[x] << endl;
    }
}
accuracy: 1
time_ms: 70
memory_kb: 11152
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;

const int limit = 102;
const int LIMIT = limit*limit*limit;
const int INF = (1<<29);

void dp(const vector<int> &reg_tetra, vector<int> &memo) {
    memo[0] = 0;
    queue<int> que;
    que.push(0);
    while (!que.empty()) {
        int now = que.front();
        que.pop();
        for (int j = 0; j < reg_tetra.size(); ++j) {
            if (now + reg_tetra[j] <= LIMIT) {
                if (memo[now+reg_tetra[j]] == INF) {
                    memo[now + reg_tetra[j]] = memo[now]+1;
                    que.push(now+reg_tetra[j]);
                }
            }
            else break;
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    vector<int> reg_tetra;
    vector<int> odd_reg_tetra;
    for (int i = 1; i*(i+1)*(i+2)/6 <= LIMIT; ++i) {
        int tet_num = i*(i+1)*(i+2)/6;
        reg_tetra.emplace_back(tet_num);
        if (tet_num % 2) odd_reg_tetra.emplace_back(tet_num);
    }

    vector<int> memo(LIMIT+1, INF);
    vector<int> odd_memo(LIMIT+1, INF);
    
    dp(reg_tetra, memo);
    dp(odd_reg_tetra, odd_memo);

    while(true) {
        int N;
        cin >> N;
        if (N == 0) break;
        cout << memo[N] << " " << odd_memo[N] << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 15236
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define ld long double
using namespace std;


int main(void){
    vector<int> tet,teto;
    vector<int> dp(1000010,1e9),dpo(1000010,1e9);
    int tmp = 1;
    int val = tmp*(tmp+1)*(tmp+2)/6;
    while(val <= 1e6){
        tet.push_back(val);
        if(val % 2 == 1){
            teto.push_back(val);
        }
        tmp++;
        val = tmp*(tmp+1)*(tmp+2)/6;
    }
    dp[0] = 0;
    for(int i = 0;i < tet.size();i++){
        for(int j = 0;j < 1e6;j++){
            if(j+1 >= tet[i]) dp[j+1] = min(dp[j+1],dp[j+1-tet[i]]+1);
        }
    }
    dpo[0] = 0;
    for(int i = 0;i < teto.size();i++){
        for(int j = 0;j < 1e6;j++){
            if(j+1 >= teto[i]) dpo[j+1] = min(dpo[j+1],dpo[j+1-teto[i]]+1);
        }
    }
    int n;
    while(true){
        cin >> n;
        if(n == 0) break;
        cout << dp[n] << " " << dpo[n] << endl;
    }
}
accuracy: 1
time_ms: 140
memory_kb: 10688
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using pii = pair<int,int>;
using pll = pair<ll,ll>;

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define el '\n'
#define spa " "
#define Yes cout << "Yes" << el
#define No cout << "No" << el
#define YES cout << "YES" << el
#define NO cout << "NO" << el
#define eps (1e-10)
#define Equals(a,b) (fabs((a) - (b)) < eps )
#define debug(x) cerr << #x << " = " << x << el

const double pi = 3.141592653589793238;
const int inf = 1073741823;
const ll infl = 1LL << 60;
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string abc = "abcdefghijklmnopqrstuvwxyz";

template<typename T1, typename T2>
std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){
    os << "{" << p.first << "," << p.second << "}";
    return os;
}

// 配列の要素を空白区切りで出力 第二引数をtrueにすると改行区切り
template<typename T> inline void print_vec(const vector<T> &v, bool split_line=false) {
    if(v.empty()){
        cout << "This vector is empty." << el;
        return;
    }
    constexpr bool isValue = is_integral<T>::value;
    for (int i = 0; i < (int)v.size(); i++) {
        if constexpr(isValue){
            if((v[i]==inf) || (v[i]==infl)) cout << 'x' << " \n"[split_line || i+1==(int)v.size()];
            else cout << v[i] << " \n"[split_line || i+1==(int)v.size()];
        }else cout << v[i] << " \n"[split_line || i+1==(int)v.size()];
    }
}

template<typename T1, typename T2> inline void print_vec(const vector<pair<T1,T2>> &v, bool split_line=false){
    if(v.empty()){
        cout << "This vector is empty." << el;
        return;
    }
    for(int i = 0; i < (int)v.size(); i++){
        cout << '{';
        auto [a,b] = v[i];
        constexpr pair<bool,bool> isValue = {is_integral<T1>::value, is_integral<T2>::value};
        if constexpr(isValue.first){
            if(a==inf || a==infl) cout << "x,";
            else cout << a << ",";
        }else cout << a << ",";
        if constexpr(isValue.second){
            if(b==inf || b==infl) cout << "x,";
            else cout << b;
        }else cout << b;
        cout << "}" << " \n"[split_line || i+1==(int)v.size()];
    }
}

/*===========================================================================================*/

#define rep(i, m, n) for(ll i = m; i < (ll)n; ++i)

void chmax(int &a, int b) {
    a = max(a, b);
}

void chmin(int &a, int b) {
    a = min(a, b);
}

const int INF = 10000000;
const int MOD = 10000;

int main() {
    vi pollock(210, 0);
    rep(i, 1, 210) pollock[i] = i*(i+1)*(i+2)/6;

    const int N = 1000000;
    vi dp(N+1, INF);
    vi dp_odd(N+1, INF);
    dp[1] = 1;
    dp_odd[1] = 1;
    rep(i, 1, N+1)rep(j, 1, 200) {
        int p = pollock[j];
        if (i == p) {
            dp[i] = 1;
            if (p % 2 == 1) {
                dp_odd[i] = 1;
            }
        }
        if (i+p <= N) {
            chmin(dp[i+p], dp[i]+1);
            if (p % 2 == 1) {
                chmin(dp_odd[i+p], dp_odd[i]+1);
            }
        }
    }

    while (true) {
        int n;
        cin >> n;
        if (n == 0) break;
        cout << dp[n] << spa << dp_odd[n] << el;
    }
}
accuracy: 1
time_ms: 230
memory_kb: 10608
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <tuple>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <cassert>
#include <unordered_set>
#include <unordered_map>
#include <cmath>
using namespace std;
typedef long long ll;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define all(v) v.begin(), v.end()

ll llpow(ll a, ll t)
{
  ll res = 1;
  rep(i, t) res *= a;
  return res;
}

ll inf = std::numeric_limits<ll>::max();

int main()
{
  vector<ll> ns;
  ll maxn = 0;
  while (true)
  {
    ll n;
    cin >> n;
    maxn = max(maxn, n);
    if (!n)
    {
      break;
    }
    ns.push_back(n);
  }
  vector<ll> san;
  rep(i, 10e6)
  {
    if (!i)
    {
      san.push_back(1);
      continue;
    }
    san.push_back(san[i - 1] + i + 1);
    if (san[i] > 10e6)
    {
      break;
    }
  }
  vector<ll> yon;
  vector<ll> yonki;
  rep(i, 10e6)
  {
    if (!i)
    {
      yon.push_back(san[i]);
      if (san[i] % 2)
      {
        yonki.push_back(san[i]);
      }
      continue;
    }
    ll num = yon[i - 1] + san[i];
    yon.push_back(num);
    if (num % 2)
    {
      yonki.push_back(num);
    }
    if (num > 10e6)
    {
      break;
    }
  }
  ll yonsz = yon.size();
  ll yonkisz = yonki.size();
  vector<ll> dp1;
  vector<ll> dp2;
  rep(i, maxn + 1)
  {
    if (!i)
    {
      dp1.push_back(0);
      dp2.push_back(0);
      continue;
    }
    dp1.push_back(inf);
    dp2.push_back(inf);
    rep(j, yonsz)
    {
      if (yon[j] > i)
      {
        break;
      }
      dp1[i] = min(dp1[i], dp1[i - yon[j]] + 1);
    }
    rep(j, yonkisz)
    {
      if (yonki[j] > i)
      {
        break;
      }
      dp2[i] = min(dp2[i], dp2[i - yonki[j]] + 1);
    }
  }
  for (auto num : ns)
  {
    cout << dp1[num] << " " << dp2[num] << endl;
  }
}
accuracy: 1
time_ms: 140
memory_kb: 18344
final_rank: 13

code_snippet: #include <stdio.h>
#include <stack>
#include <math.h>
using namespace std;

int main(){
    int n;
    const int MAXN = 1000000;
    const int INF = 20000000;
    // テトラヘドロン数テーブル（183個）
    int table[183];
    for(int i = 0; i < 183; i++){
        table[i] = i*(i+1)*(i+2)/6;
    }

    // DP 配列
    int* dp     = new int[MAXN];
    int* odd_dp = new int[MAXN];
    for(int i = 0; i < MAXN; i++){
        dp[i]     = INF;
        odd_dp[i] = INF;
    }
    dp[0]     = 0;
    odd_dp[0] = 0;

    // DP 前計算 (1 以上 MAXN-1 まで)
    for(int i = 1; i < MAXN; i++){
        // k < 183 を明示して範囲外アクセスを防ぐ
        for(int k = 1; k < 183 && table[k] <= i; k++){
            // 普通のテトラヘドロン数を使う遷移
            dp[i] = min(dp[i], dp[i - table[k]] + 1);
            // 奇数テトラヘドロン数だけを使う遷移
            if(table[k] % 2 == 1){
                odd_dp[i] = min(odd_dp[i], odd_dp[i - table[k]] + 1);
            }
        }
    }

    // 入力受け取り＆出力
    while (scanf("%d", &n) == 1 && n != 0) {
        printf("%d %d\n", dp[n], odd_dp[n]);
    }

    delete[] dp;
    delete[] odd_dp;
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 10084
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
//#include <atcoder/all>
//using namespace atcoder;


template<typename T> using vc = vector<T>;//prioriy_queueに必要なのでここにこれ書いてます
template<typename T> using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
using ull = unsigned long long;
ll INF = 3e18;
double pi = 3.14159265358979;
using ld = long double;
using bl = bool;
//using mint = modint998244353;
//using mint = modint1000000007;
//using mint = modint;//使うときはコメントアウトを外す
//mint::set_mod(m);//使うときはコメントアウトを外す

template<class T> using pq = priority_queue<T, vc<T>>;//大きい順
template<class T> using pq_g = priority_queue<T, vc<T>, greater<T>>;//小さい順
//-----------------------------------



//-------------2.配列系--------------
using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>; using vvvvl = vv<vvl>;
using vs = vc<string>; using vvs = vv<string>; using vvvs = vv<vs>;
using vb = vc<bl>; using vvb = vv<bl>; using vvvb = vv<vb>;
using vld = vc<ld>; using vvld = vv<ld>; using vvvld = vv<vld>;
using pll = pair<ll, ll>;
//using vmint = vc<mint>; using vvmint = vv<mint>; using vvvmint = vv<vmint>;

#define rep(i,n) for(ll i = 0; i < (n); ++i)//↓でrepを使うので書いてます
template<class T>istream& operator>>(istream& i, vc<T>& v) { rep(j, size(v))i >> v[j]; return i; }

using ar2 = array<ll, 2>;

//----------------------------------



//--------3.コード短縮化とか---------
#define rep(i,n) for(ll i = 0; i < (n); ++i)
#define rrep(i,n) for(ll i = 1; i <= (n); ++i)
#define drep(i,n) for(ll i = (n)-1; i >= 0; --i)

#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()

#define chmax(x,y) x = max(x,y)
#define chmin(x,y) x = min(x,y)

#define pb push_back
#define eb emplace_back
#define em emplace
#define pob pop_back


#define Yes cout<<"Yes"<<endl
#define No cout<<"No"<<endl
#define YN {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}// if(a==b)YN;
#define dame cout<<-1<<endl


#define vc_unique(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define vc_rotate(v) rotate(v.begin(),v.begin()+1,v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(),v.end())

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

#define yu_qurid(x,y) ((x)*(x)+(y)*(y))//ユークリッド距離 sqrtはしてないなので注意
#define mannhattan(x1,x2,y1,y2) (abs(x1-x2)+abs(y1-y2)) // マンハッタン距離 = |x1-x2|+|y1-y2|

//if (regex_match(s, regex("")))YN;//文字列sの判定を行う。コメントアウトを外して「""」の中に判定する内容を入れる

//-------------------------------




//---------4.グリッド系----------
vl dx = { 1,0,-1,0 };
//vl dx={1,1,0,-1,-1,-1,0,1};
vl dy = { 0,1,0,-1 };
//vl dy={0,1,1,1,0,-1,-1,-1};

bool out_grid(ll i, ll j, ll h, ll w) {//trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_kaiten(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//時計回りに90°回転
//#define vvl_kaiten(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_kaiten(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//文字列版 時計回りに90°回転
//#define vs_kaiten(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転


#define vvl_tenti(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][i]=v[i][j];swap(nx,v);}
#define vs_tenti(v) {ll n = size(v); vs nx(n, string(n,'.')); rep(i, n)rep(j, n)nx[j][i] = v[i][j]; swap(nx, v);}

//回転、転置はn*nしか使えないことに注意

//--------------------------------

int main() {
    const ll mx = 1000000;
    vl a;
    for(ll i = 1; i*(i+1)*(i+2)/6 < mx; i++){
        a.pb(i*(i+1)*(i+2)/6);
    }
    ll m = a.size();

    vl dp(mx, INF), odd_dp(mx, INF);
    dp[0] = odd_dp[0] = 0;
    rep(i, mx){
        rep(j, m){
            if(i+a[j] > mx) break;
            chmin(dp[i+a[j]], dp[i]+1);
        }
    }
    rep(i, mx){
        rep(j, m){
            if(i+a[j] > mx) break;
            if(a[j] % 2 == 0) continue;
            chmin(odd_dp[i+a[j]], odd_dp[i]+1);
        }
    }

    while(1){
        ll n; cin >> n;
        if(n == 0) break;
        
        cout << dp[n] << " " << odd_dp[n] << endl;
    }
}
accuracy: 1
time_ms: 240
memory_kb: 18640
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using vi = vector<int>;
using vl = vector<long long>;
using vs = vector<string>;
using vc = vector<char>;
using vb = vector<bool>;
using vpii = vector<pair<int, int>>;
using vpll = vector<pair<long long, long long>>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<long long>>;
using vvc = vector<vector<char>>;
using vvvi = vector<vector<vector<int>>>;
using pii = pair<int, int>;
using vvb = vector<vector<bool>>;
using Graph = vector<vector<ll>>;
const ll LINF = 1001002003004005006ll;
const int INF = 1001001001;
const int MOD = 998244353;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep3(i, m, n) for (int i = (m); i < (int)(n); i++)
#define rrep(i, m, n) for (int i = (m); i >= (int)(n); i--)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }
template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }

vi dx4 = {1, 0, -1, 0}, dy4 = {0, 1, 0, -1};
vi dx8 = {1, 1, 1, 0, 0, -1, -1, -1}, dy8 = {1, 0, -1, 1, -1, 1, 0, -1};

int main()
{
    vl all, odd;
    ll i = 1;
    while (1)
    {
        ll num = i * (i + 1) * (i + 2) / 6;
        if (num > 1000000LL)
        {
            break;
        }
        all.push_back(num);
        if (num % 2 == 1)
        {
            odd.push_back(num);
        }
        i++;
    }
    vl dp_all(1000000 + 5, LINF);
    dp_all[0] = 0;

    for (auto x : all)
    {
        for (ll i = 0; i <= 1000000; i++)
        {
            if (i + x < 1000000 + 5)
            {
                dp_all[i + x] = min(dp_all[i + x], dp_all[i] + 1);
            }
        }
    }
    vl dp_odd(1000000 + 5, LINF);
    dp_odd[0] = 0;

    for (auto x : odd)
    {
        for (ll i = 0; i <= 1000000; i++)
        {
            if (i + x < 1000000 + 5)
            {
                dp_odd[i + x] = min(dp_odd[i + x], dp_odd[i] + 1);
            }
        }
    }

    while (1)
    {
        // 宣言・入力の受け取り
        ll n;
        cin >> n;
        // 終了条件
        if (n == 0)
        {
            break;
        }
        // 宣言・入力の受け取り

        // solve

        // 出力
        cout << dp_all[n] << ' ' << dp_odd[n] << '\n';
    }
    return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 18484
final_rank: 14