Problem p02669 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define REP(i, n) for (int i = 0; i < n; i++)
#define ALL(a) (a).begin(), (a).end()
typedef vector<int> vi;
const int INF = 1LL << 60; // 10e18+10e17ちょっとくらい
const int MOD = 1000000007;
const int MAX_N = 200100;

int N, A, B, C, D;
map<int, int> memo;
int solve(int num) {
  if (num == 0)
    return 0;
  if (num == 1)
    return D;
  if (memo.count(num)) {
    return memo[num];
  }

  int cost = INF;
  int add;

  if (cost / D > num)
    cost = D * num;

  if (num % 2 == 0) {
    add = A;
    cost = min(cost, solve(num / 2) + add);
  } else {
    int tmp = num;
    while (true) {
      tmp++;
      if (tmp % 2 == 0) {
        add = A + D * abs(num - tmp);
        cost = min(cost, solve(tmp / 2) + add);
        break;
      }
    }
    tmp = num;
    while (true) {
      tmp--;
      if (tmp % 2 == 0) {
        add = A + D * abs(num - tmp);
        cost = min(cost, solve(tmp / 2) + add);
        break;
      }
    }
  }

  if (num % 3 == 0) {
    add = B;
    cost = min(cost, solve(num / 3) + add);
  } else {
    int tmp = num;
    while (true) {
      tmp++;
      if (tmp % 3 == 0) {
        add = B + D * abs(num - tmp);
        cost = min(cost, solve(tmp / 3) + add);
        break;
      }
    }
    tmp = num;
    while (true) {
      tmp--;
      if (tmp % 3 == 0) {
        add = B + D * abs(num - tmp);
        cost = min(cost, solve(tmp / 3) + add);
        break;
      }
    }
  }

  if (num % 5 == 0) {
    add = C;
    cost = min(cost, solve(num / 5) + add);
  } else {
    int tmp = num;
    while (true) {
      tmp++;
      if (tmp % 5 == 0) {
        add = C + D * abs(num - tmp);
        cost = min(cost, solve(tmp / 5) + add);
        break;
      }
    }
    tmp = num;
    while (true) {
      tmp--;
      if (tmp % 5 == 0) {
        add = C + D * abs(num - tmp);
        cost = min(cost, solve(tmp / 5) + add);
        break;
      }
    }
  }
  memo[num] = cost;
  return cost;
}

signed main() {
  //  以降 cin の入力元が 'input.txt' になる
  // std::ifstream in("input.txt");
  // std::cin.rdbuf(in.rdbuf());
  int T;
  cin >> T;
  REP(i, T) {
    cin >> N >> A >> B >> C >> D;
    memo.clear();
    cout << solve(N) << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define REP(i, n) for (int i = 0; i < n; i++)
#define ALL(a) (a).begin(), (a).end()
typedef vector<int> vi;
const int INF = 1LL << 60; // 10e18+10e17ちょっとくらい
const int MOD = 1000000007;
const int MAX_N = 200100;

int N, A, B, C, D;
map<int, int> memo;
void solve(int num, int cost) {
  if (memo.count(num)) {
    if (memo[num] <= cost)
      return;
    else
      memo[num] = cost;
  } else
    memo[num] = cost;

  if (num == 1) {
    if (memo.count(0))
      memo[0] = min(memo[0], cost + D);
    else
      memo[0] = cost + D;
    return;
  }

  int add;
  if (num % 2 == 0) {
    add = min(num / 2 * D, A);
    if (add <= 0)
      add = A;
    solve(num / 2, cost + add);
  } else {
    int tmp = num;
    while (true) {
      tmp++;
      if (tmp % 2 == 0) {
        add = min(abs(num - tmp / 2) * D, A + D * abs(num - tmp));
        if (add <= 0)
          add = A + D * abs(num - tmp);
        solve(tmp / 2, cost + add);
        break;
      }
    }
    tmp = num;
    while (true) {
      tmp--;
      if (tmp % 2 == 0) {
        add = min(abs(num - tmp / 2) * D, A + D * abs(num - tmp));
        if (add <= 0)
          add = A + D * abs(num - tmp);
        solve(tmp / 2, cost + add);
        break;
      }
    }
  }

  if (num % 3 == 0) {
    add = min(num / 3 * 2 * D, B);
    if (add <= 0)
      add = B;
    solve(num / 3, cost + add);
  } else {
    int tmp = num;
    while (true) {
      tmp++;
      if (tmp % 3 == 0) {
        add = min(abs(num - tmp / 3) * D, B + D * abs(num - tmp));
        if (add <= 0)
          add = B + D * abs(num - tmp);
        solve(tmp / 3, cost + add);
        break;
      }
    }
    tmp = num;
    while (true) {
      tmp--;
      if (tmp % 3 == 0) {
        add = min(abs(num - tmp / 3) * D, B + D * abs(num - tmp));
        if (add <= 0)
          add = B + D * abs(num - tmp);
        solve(tmp / 3, cost + add);
        break;
      }
    }
  }

  if (num % 5 == 0) {
    add = min(num / 5 * 4 * D, C);
    if (add <= 0)
      add = C;
    solve(num / 5, cost + add);
  } else {
    int tmp = num;
    while (true) {
      tmp++;
      if (tmp % 5 == 0) {
        add = min(abs(num - tmp / 5) * D, C + D * abs(num - tmp));
        if (add <= 0)
          add = C + D * abs(num - tmp);
        solve(tmp / 5, cost + add);
        break;
      }
    }
    tmp = num;
    while (true) {
      tmp--;
      if (tmp % 5 == 0) {
        add = min(abs(num - tmp / 5) * D, C + D * abs(num - tmp));
        if (add <= 0)
          add = C + D * abs(num - tmp);
        solve(tmp / 5, cost + add);
        break;
      }
    }
  }
}

signed main() {
  //  以降 cin の入力元が 'input.txt' になる
  // std::ifstream in("input.txt");
  // std::cin.rdbuf(in.rdbuf());
  int T;
  cin >> T;
  REP(i, T) {
    cin >> N >> A >> B >> C >> D;
    memo.clear();
    solve(N, 0);
    cout << memo[0] << endl;
  }

  return 0;
}