Problem p02669 (C++) — buggy submission, verdict: Runtime Error

#include <climits>
#include <cmath>
#include <iostream>
#include <map>
#include <set>
#include <vector>

using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

#define MOD 1000000007LL

map<ll, ll> t;

int T;
ll N, A, B, C, D;
ll minc;

ll count(ll, ll, ll);

int main() {
  ll ans;

  cin >> T;

  for (int i = 0; i < T; i++) {
    minc = LLONG_MAX;
    cin >> N >> A >> B >> C >> D;
    ans = count(N, 0, 0);
    cout << ans << endl;
    // printf("t.size()=%lu\\n", t.size());
    /*
    for (auto it=t.begin(); it!=t.end(); it++) {
      printf("t[%lld]=%lld, ", it->first, it->second);
    }
    printf("\\n");
    */
    t.clear();
  }

  return 0;
}

ll count(ll num, ll coins, ll d) {
  ll a1, a2;
  decltype(t)::iterator itt;

  // printf("%*scount(%lld, %lld, %lld)\\n", (int)d, "", num, coins, d);

  if (num == 1) {
    if (coins + D < minc)
      minc = coins + D;
    // printf("%*scount(%lld, %lld, %lld)=%lld\\n", (int)d, "", num, coins, d,
    // D);
    return D;
  }
  if (num == 0) {
    if (coins < minc)
      minc = coins;
    // printf("%*scount(%lld, %lld, %lld)=0\\n", (int)d, "", num, coins, d);
    return 0;
  }

  //  num*D < LLONG_MAX
  //  num < LLONG_MAX/D
  if (num < LLONG_MAX / D) {
    a1 = num * D;
  } else {
    a1 = LLONG_MIN;
  }
  itt = t.find(num); // num から0までの最小値（確定値）
  if (itt != t.end()) {
    // printf("%*scount(%lld, %lld, %lld)=%lld m\\n", (int)d, "", num, coins, d,
    // itt->second);
    return itt->second;
  }

  // 2で割る
  if (num % 2 == 0) {
    a2 = count(num / 2, coins + A, d + 1) + A;
    if (a1 < 0 || a2 < a1)
      a1 = a2;
  } else {
    a2 = count((num + 1) / 2, coins + D + A, d + 1) + D + A;
    if (a1 < 0 || a2 < a1)
      a1 = a2;
    a2 = count((num - 1) / 2, coins + D + A, d + 1) + D + A;
    if (a1 < 0 || a2 < a1)
      a1 = a2;
  }

  // 3で割る
  switch (num % 3) {
  case 0:
    a2 = count(num / 3, coins + B, d + 1) + B;
    if (a1 < 0 || a2 < a1)
      a1 = a2;
    break;
  case 1:
    a2 = count((num - 1) / 3, coins + D + B, d + 1) + D + B;
    if (a1 < 0 || a2 < a1)
      a1 = a2;
    break;
  case 2:
    a2 = count((num + 1) / 3, coins + D + B, d + 1) + D + B;
    if (a1 < 0 || a2 < a1)
      a1 = a2;
    break;
  }

  // 5で割る
  switch (num % 5) {
  case 0:
    a2 = count(num / 5, coins + C, d + 1) + C;
    if (a1 < 0 || a2 < a1)
      a1 = a2;
    break;
  case 1:
    a2 = count((num - 1) / 5, coins + D + C, d + 1) + D + C;
    if (a1 < 0 || a2 < a1)
      a1 = a2;
    break;
  case 2:
    a2 = count((num - 2) / 5, coins + D * 2 + C, d + 1) + D * 2 + C;
    if (a1 < 0 || a2 < a1)
      a1 = a2;
    break;
  case 3:
    a2 = count((num + 2) / 5, coins + D * 2 + C, d + 1) + D * 2 + C;
    if (a1 < 0 || a2 < a1)
      a1 = a2;
    break;
  case 4:
    a2 = count((num + 1) / 5, coins + D + C, d + 1) + D + C;
    if (a1 < 0 || a2 < a1)
      a1 = a2;
    break;
  }

  if (a1 < 0) {
    // printf("%*scount(%lld, %lld, %lld)=%lld\\n", (int)d, "", num, coins, d,
    // a1);
    return LLONG_MIN;
  }

  itt = t.find(num);
  if (itt != t.end()) {
    if (itt->second > a1) {
      t.erase(num);
      t.emplace(num, a1);
      // printf("x memo(%lld, %lld)\\n", num, a1);
    }
  } else {
    t.emplace(num, a1);
    // printf("memo(%lld, %lld) %lu\\n", num, a1, t.size());
  }

  // printf("%*scount(%lld, %lld, %lld)=%lld\\n", (int)d, "", num, coins, d, a1);
  return a1;
}

/*
  A,B,C,Dのどれかを使って枚数を増やしていく
  ちょうどNになる
  Nを超える→NになるまでDで減らす
  */


Error: -11

Fixed submission:

#include <cmath>
#include <iostream>
#include <map>
#include <set>
#include <vector>

using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

#define MOD 1000000007LL

map<ll, ll> m;

int T;
ll N, A, B, C, D;
ll minc;

ll count(ll, ll);

int main() {
  ll ans;

  cin >> T;

  for (int i = 0; i < T; i++) {
    minc = -1;
    cin >> N >> A >> B >> C >> D;
    m.emplace(1, D);
    ans = count(1, D);
    cout << ans << endl;
    m.clear();
  }

  return 0;
}

ll count(ll num, ll coins) {
  ll nn;
  ll nc;
  ll a1, a2;
  //  decltype(m)::iterator it;

  // printf("count(%lld, %lld)\\n", num, coins); fflush(stdout);
  if (num == N) {
    // printf("num == N\\n");
    if (minc < 0 || minc > coins)
      minc = coins;
    // printf("=%lld(%lld)\\n", coins, minc);
    return coins;
  }
  if (num > N) {
    // printf("num > N\\n");
    coins += (num - N) * D;
    if (minc < 0 || minc > coins)
      minc = coins;
    // printf("=%lld(%lld)\\n", coins, minc);
    return coins;
  }

  nn = num * 2;
  nc = coins + A;
  if (minc < 0 || minc > nc) {
    a1 = count(nn, nc);
  }

  nn = num * 3;
  nc = coins + B;
  if (minc < 0 || minc > nc) {
    a2 = count(nn, nc);
    if (a2 < a1)
      a1 = a2;
  }

  nn = num * 5;
  nc = coins + C;
  if (minc < 0 || minc > nc) {
    a2 = count(nn, nc);
    if (a2 < a1)
      a1 = a2;
  }

  nn = num + 1;
  nc = coins + D;
  if (minc < 0 || minc > nc) {
    a2 = count(nn, nc);
    if (a2 < a1)
      a1 = a2;
  }

  nn = num - 1;
  nc = coins + D;
  if (nn > 0 && (minc < 0 || minc > nc)) {
    a2 = count(nn, nc);
    if (a2 < a1)
      a1 = a2;
  }
  if (minc < 0 || minc > a1)
    minc = a1;
  /*
  it = m.find(nn);
  if (it != m.end()) {
    if (it->second > nc) {
      m.erase(nn);
      m.emplace(nn, nc);
    }
  } else {
    m.emplace(nn, nc);
  }
    */
  return a1;
}

/*
  A,B,C,Dのどれかを使って枚数を増やしていく
  ちょうどNになる
  Nを超える→NになるまでDで減らす
  */