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

#include <bits/stdc++.h>

#include <iostream>
// #include <algorithm>
//  #include <iomanip>
#define ll long long
#define map unordered_map
#define set unordered_set
#define pll pair<ll, ll>
#define vll vector<ll>
#define mll map<ll, ll>

using namespace std;

const ll MOD = 1000000007LL;
const ll INF = (1LL << 60LL);

class BitComb {
private:
  ll _digits;
  ll _base;
  ll _data[512];
  ll _finished;
  ll _i;

public:
  BitComb(ll digits, ll base) {
    _digits = digits;
    _base = base;
    _finished = false;
    _i = 0;
    fill_n(_data, 512, 0);
  }

  void next() {
    if (_finished) {
      return;
    }
    for (ll i = 0; i < _digits; i++) {
      if (_data[i] + 1 < _base) {
        _data[i] += 1;
        break;
      } else {
        _data[i] = 0;

        if (i == _digits - 1) {
          _finished = true;
          break;
        }
      }
    }
  }

  ll *data() { return _data; }

  void print() {
    for (ll i = _digits - 1; i >= 0; i--) {
      cout << _data[i];
    }
    cout << endl;
  }

  bool finished() { return _finished; }
};

ll cache_x[20][50000];
ll cache_y[20][50000];

int main() {
  ll N;
  scanf("%lld", &N);
  vector<tuple<ll, ll, ll>> list;

  for (ll i = 0; i < N; i++) {
    ll x, y, p;
    scanf("%lld %lld %lld", &x, &y, &p);
    list.emplace_back(make_tuple(x, y, p));
    // cout << get<0>(list[i]) << endl;
  }

  ll zero_list[20];
  // ll cache[20][20][3];
  // ll cache[20][20][3];
  // for (ll i = 0; i < N; i++) {
  //   ll x1 = get<0>(list[i]);
  //   ll y1 = get<1>(list[i]);
  //   ll p1 = get<2>(list[i]);

  //   ll dist_zero = min(abs(x1), abs(y1));

  //   zero_list[i] = dist_zero * p1;

  //   for (ll j = 0; j < N; j++) {
  //     ll x2 = get<0>(list[j]);
  //     ll y2 = get<1>(list[j]);

  //     cache[i][j][0] = dist_zero * p1;
  //     cache[i][j][1] = min(dist_zero, abs(x2 - x1)) * p1;
  //     cache[i][j][2] = min(dist_zero, abs(y2 - y1)) * p1;
  //   }
  // }

  {
    auto bc = BitComb(N, 2);
    while (!bc.finished()) {
      for (ll i = 0; i < N; i++) {
        ll x1 = get<0>(list[i]);
        ll y1 = get<1>(list[i]);
        ll p = get<2>(list[i]);

        ll key = 0;
        ll dist_x = abs(x1);
        ll dist_y = abs(y1);
        for (ll i = 0; i < N; i++) {
          if (bc.data()[i]) {
            key += (1LL << i);

            ll x2 = get<0>(list[i]);
            ll y2 = get<1>(list[i]);

            dist_x = min(dist_x, abs(x1 - x2));
            dist_y = min(dist_y, abs(y1 - y2));
          }
        }

        cache_x[i][key] = dist_x * p;
        cache_y[i][key] = dist_y * p;
      }
      bc.next();
    }
  }

  mll m;
  for (ll i = 0; i <= N; i++) {
    m[i] = INF;
  }

  auto bc = BitComb(N, 3);

  while (!bc.finished()) {
    ll line_count = 0;
    ll cache_key_x = 0;
    ll cache_key_y = 0;

    for (ll i = 0; i < N; i++) {
      if (bc.data()[i] == 1) {
        cache_key_x += (1LL << i);
        line_count++;
      }
      if (bc.data()[i] == 2) {
        cache_key_y += (1LL << i);
        line_count++;
      }
    }

    ll sum = 0;

    for (ll i = 0; i < N; i++) {
      // ll point = zero_list[i];
      // for (ll j = 0; j < N; j++) {
      //   ll id = bc.data()[j];
      //   if (id != 0) {
      //     ll point2 = cache[i][j][id];

      //     point = min(point, point2);
      //   }
      // }

      ll px = cache_x[i][cache_key_x];
      ll py = cache_y[i][cache_key_y];

      ll point = min(px, py);

      sum += point;
    }

    m[line_count] = min(m[line_count], sum);

    bc.next();
  }

  for (ll i = 0; i <= N; i++) {
    cout << m[i] << endl;
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#include <iostream>
// #include <algorithm>
//  #include <iomanip>
#define ll long long
#define map unordered_map
#define set unordered_set
#define pll pair<ll, ll>
#define vll vector<ll>
#define mll map<ll, ll>

using namespace std;

const ll MOD = 1000000007LL;
const ll INF = (1LL << 60LL);

class BitComb {
private:
  ll _digits;
  ll _base;
  ll _data[512];
  ll _finished;
  ll _i;

public:
  BitComb(ll digits, ll base) {
    _digits = digits;
    _base = base;
    _finished = false;
    _i = 0;
    fill_n(_data, 512, 0);
  }

  void next() {
    if (_finished) {
      return;
    }
    for (ll i = 0; i < _digits; i++) {
      if (_data[i] + 1 < _base) {
        _data[i] += 1;
        break;
      } else {
        _data[i] = 0;

        if (i == _digits - 1) {
          _finished = true;
          break;
        }
      }
    }
  }

  ll *data() { return _data; }

  void print() {
    for (ll i = _digits - 1; i >= 0; i--) {
      cout << _data[i];
    }
    cout << endl;
  }

  bool finished() { return _finished; }
};

int main() {
  ll N;
  scanf("%lld", &N);
  vector<tuple<ll, ll, ll>> list;

  for (ll i = 0; i < N; i++) {
    ll x, y, p;
    scanf("%lld %lld %lld", &x, &y, &p);
    list.emplace_back(make_tuple(x, y, p));
    // cout << get<0>(list[i]) << endl;
  }

  ll zero_list[20];
  ll cache[20][20][3];
  for (ll i = 0; i < N; i++) {
    ll x1 = get<0>(list[i]);
    ll y1 = get<1>(list[i]);
    ll p1 = get<2>(list[i]);

    ll dist_zero = min(abs(x1), abs(y1));

    zero_list[i] = dist_zero * p1;

    for (ll j = 0; j < N; j++) {
      ll x2 = get<0>(list[j]);
      ll y2 = get<1>(list[j]);

      cache[i][j][0] = dist_zero * p1;
      cache[i][j][1] = min(dist_zero, abs(x2 - x1)) * p1;
      cache[i][j][2] = min(dist_zero, abs(y2 - y1)) * p1;
    }
  }

  mll m;
  for (ll i = 0; i <= N; i++) {
    m[i] = INF;
  }

  auto bc = BitComb(N, 3);

  while (!bc.finished()) {
    ll line_count = 0;
    for (ll i = 0; i < N; i++) {
      if (bc.data()[i] != 0) {
        line_count++;
      }
    }

    ll sum = 0;

    for (ll i = 0; i < N; i++) {
      ll point = zero_list[i];
      for (ll j = 0; j < N; j++) {
        ll id = bc.data()[j];
        if (id != 0) {
          ll point2 = cache[i][j][id];

          point = min(point, point2);
        }
      }

      sum += point;
    }

    m[line_count] = min(m[line_count], sum);

    bc.next();
  }

  for (ll i = 0; i <= N; i++) {
    cout << m[i] << endl;
  }
}