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

#include <bits/stdc++.h>

using namespace std;

using ll = long long int;
inline void fast_io() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
};

ll N;
ll INF = 1e18;
struct P {
  ll x, y, p;
};
vector<P> Ps;

void input() {
  fast_io();
  cin >> N;
  Ps.resize(N);
  for (int i = 0; i < N; i++) {
    ll x, y, p;
    cin >> x >> y >> p;
    Ps[i] = P{x, y, p};
  }
}

inline void chmin(ll &a, ll b) {
  if (a > b)
    a = b;
}

vector<ll> memo[1 << 15][2];
vector<ll> xscore(int bit, bool isX = true) {
  if (memo[bit][isX].size() > 0)
    return memo[bit][isX];
  vector<int> xline;
  xline.push_back(0);
  for (int i = 0; i < N; i++) {
    if (bit >> i & 1) {
      if (isX)
        xline.push_back(Ps[i].x);
      else
        xline.push_back(Ps[i].y);
    }
  }
  vector<ll> ret(N, 0);
  for (int i = 0; i < N; i++) {
    if (bit >> i & 1) {
      ret[i] = 0;
      continue;
    };
    ll sc = INF;
    for (ll x : xline) {
      if (isX)
        chmin(sc, abs(x - Ps[i].x) * Ps[i].p);
      else
        chmin(sc, abs(x - Ps[i].y) * Ps[i].p);
    }
    ret[i] = sc;
  }
  return memo[bit][isX] = ret;
}

ll score(int K, int bit, int sign) {
  ll ret = 0;
  int mask = 0;
  int k = 0;
  int cnt = 0;
  while (cnt < K) {
    while ((bit >> k & 1) == 0)
      k++;
    if (sign >> cnt & 1)
      mask |= (1 << k);
    k++;
    cnt++;
  }
  auto xcost = xscore(mask, true);
  auto ycost = xscore(bit & (~mask), false);
  for (int i = 0; i < N; i++)
    ret += min(xcost[i], ycost[i]);
  return ret;
}

int solve() {
  vector<ll> ans(N + 1, INF);

  // ザ・前処理
  int Kmax;
  set<int> Xs, Ys;
  for (int i = 0; i < N; i++) {
    Xs.insert(Ps[i].x);
    Ys.insert(Ps[i].y);
  }
  Kmax = min(Xs.size(), Ys.size());
  for (int bit = 0; bit < (1 << N); bit++) {
    xscore(bit, true);
    xscore(bit, false);
  }

  for (int bit = 0; bit < (1 << N); bit++) {
    int k = __builtin_popcount(bit);
    if (k > Kmax)
      continue;
    if (ans[k] == 0)
      continue;
    // bitで線を通す点をきめて
    // signでx軸に平行かy軸に平行かきめる。
    for (int sign = 0; sign < (1 << k); sign++) {
      if (ans[k] == 0)
        break;
      chmin(ans[k], score(k, bit, sign));
    }
    if (ans[k] == 0)
      for (int i = k; i < N; i++)
        chmin(ans[i + 1], ans[i]);
  }
  for (int i = 0; i <= N; i++)
    cout << ans[i] << "\\n";
  return 0;
}

int main() {
  input();
  solve();
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#ifdef __DEBUG__
#define DBG(X) cout << #X << " = " << (X) << endl;
#define SAY(X) cout << (X) << endl;
#else
#define DBG(X)
#define SAY(X)
#endif

using namespace std;

using ll = long long int;
using ull = unsigned long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

inline void fast_io() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
};

ll N;
ll INF = 1e18;
struct P {
  ll x, y, p;
};

vector<P> Ps;
void input() {
  fast_io();
  cin >> N;
  Ps.resize(N);
  for (int i = 0; i < N; i++) {
    ll x, y, p;
    cin >> x >> y >> p;
    Ps[i] = P{x, y, p};
  }
}

void chmin(ll &a, ll b) {
  if (a > b)
    a = b;
}

ll score(int bit, vector<ll> xline, vector<ll> yline) {
  ll ret = 0;
  for (int i = 0; i < N; i++) {
    if (bit >> i & 1)
      continue;
    ll sc = INF;
    for (ll x : xline) {
      chmin(sc, abs(x - Ps[i].x) * Ps[i].p);
    }
    for (ll y : yline) {
      chmin(sc, abs(y - Ps[i].y) * Ps[i].p);
    }
    ret += sc;
  }
  return ret;
}

int solve() {
  vector<ll> ans(N + 1, INF);
  int Kmax;
  set<int> Xs, Ys;
  for (int i = 0; i < N; i++) {
    Xs.insert(Ps[i].x);
    Ys.insert(Ps[i].y);
  }
  Kmax = min(Xs.size(), Ys.size());

  for (int bit = 0; bit < (1 << N); bit++) {
    int k = __builtin_popcount(bit);
    if (k > Kmax)
      continue;
    if (ans[k] == 0)
      continue;
    // bitで線を通す点をきめて
    // signでx軸に平行かy軸に平行かきめる。
    for (int sign = 0; sign < (1 << k); sign++) {
      if (ans[k] == 0)
        break;
      vector<ll> xline, yline;
      xline.push_back(0LL);
      yline.push_back(0LL);
      int cnt = 0;
      for (int i = 0; i < N; i++) {
        if (bit >> i & 1) {
          if (sign >> cnt & 1)
            xline.push_back(Ps[i].x);
          else
            yline.push_back(Ps[i].y);
          cnt++;
        }
      }
      chmin(ans[k], score(bit, xline, yline));
    }
    if (ans[k] == 0)
      for (int i = k; i < N - 1; i++)
        chmin(ans[i + 1], ans[i]);
  }
  ans[N] = 0;
  for (int i = 0; i <= N; i++)
    cout << ans[i] << "\\n";
  return 0;
}

int main() {
  input();
  solve();
  return 0;
}