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

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const ll INF = 4e18;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int T;
  cin >> T;
  while (T--) {
    ll N, A, B, C, D;
    cin >> N >> A >> B >> C >> D;
    vector<pair<int, ll>> keks = {{2, A}, {3, B}, {5, C}};
    map<ll, ll> dp;
    function<ll(ll)> solve = [&](ll N) {
      if (N == 0)
        return 0LL;
      if (N == 1)
        return D;
      if (dp.count(N)) {
        return dp[N];
      }
      ll ans = INF;
      if (ans / D >= N)
        ans = min(ans, N * D);
      for (auto z : keks) {
        int num;
        ll cost;
        tie(num, cost) = z;
        ans = min(ans, solve(N / num) + D * (N % num) + cost);
        if (N % num) {
          ans = min(ans, solve((N / num) + 1) + D * (num - (N % num)) + cost);
        }
      }
      return dp[N] = ans;
    };
    cout << solve(N) << "\\n";
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const ll INF = 1e18;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int T;
  cin >> T;
  while (T--) {
    ll N, A, B, C, D;
    cin >> N >> A >> B >> C >> D;
    ll ans = INF;
    auto go = [&](int ca, int cb, int cc) {
      // cerr << "solving " << ca << " " << cb << " " << cc << "\\n";
      // return 5ll;
      vector<pair<int, ll>> layer;
      ll cur = N;
      layer.emplace_back(1, N);
      for (int z = 0; z < cc; ++z) {
        cur /= 5;
        layer.emplace_back(5, cur);
      }
      for (int z = 0; z < cb; ++z) {
        cur /= 3;
        layer.emplace_back(3, cur);
      }
      // return 5ll;
      for (int z = 0; z < ca; ++z) {
        cur /= 2;
        layer.emplace_back(2, cur);
      }
      vector<ll> dp(2);
      dp[0] = 0;
      dp[1] = 1;
      for (int z = 0; z + 1 < layer.size(); ++z) {
        vector<ll> ndp(2, INF);
        for (int i = 0; i < 2; ++i) {
          for (int j = 0; j < 2; ++j) {
            ndp[j] = min(ndp[j], dp[i] + abs(layer[z + 1].first *
                                                 (layer[z + 1].second + j) -
                                             layer[z].second - i));
          }
        }
        dp = ndp;
        // for (int i = 0; i < 2; ++i) cout << dp[i] << " "; cout << "\\n";
      }
      ll ans = INF;
      for (int z = 0; z < 2; ++z) {
        if (INF / D >= (layer.back().second + z + dp[z]))
          ans = min(ans, layer.back().second + z + dp[z]);
      }
      // for (int z = 0; z < layer.size(); ++z) {
      // }
      ans *= D;
      ans += A * ca + B * cb + C * cc;
      // cerr << "NANI\\n";
      return ans;
    };
    auto ok = [&](int ca, int cb, int cc) {
      ll cur = 0;
      while (cc--) {
        cur *= 5;
        if (cur > INF)
          return false;
      }
      while (cb--) {
        cur *= 3;
        if (cur > INF)
          return false;
      }
      while (ca--) {
        cur *= 2;
        if (cur > INF)
          return false;
      }
      return true;
    };
    for (int ca = 0; ca <= 60; ++ca) {
      for (int cb = 0; cb <= 60; ++cb) {
        if (!ok(ca, cb, 0))
          break;
        for (int cc = 0; cc <= 60; ++cc) {
          if (!ok(ca, cb, cc))
            break;
          ans = min(ans, go(ca, cb, cc));
        }
      }
    }
    // cout << go(2, 1, 0) << "\\n";
    cout << ans << "\\n";
  }
}