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

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define maxch(x, y) x = mmax(x, y)
#define minch(x, y) x = mmin(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt __builtin_popcountll

#define INF 1e18
#define mod 1000000007

ll N;
vector<ll> X, Y, M;
ll res[20], dmin[(1 << 16)];

ll calcd(const vector<ll> &st, bool dir, ll z) {
  ll dsum = 0;
  rep(i, st.size()) {
    if (!dir) { // x
      dsum += (ll)abs(z - Y[st[i]]) * M[st[i]];
    } else { // y
      dsum += (ll)abs(z - X[st[i]]) * M[st[i]];
    }
  }
  return dsum;
}

ll calcx(const vector<ll> &st) {
  ll sz = st.size();
  ll mmid = 0, msum = 0;
  rep(i, sz) mmid += M[st[i]];
  mmid /= 2;

  vector<ll> ord(sz);
  rep(i, sz) ord[i] = i;
  sort(all(ord), [&](const ll &a, const ll &b) { return X[st[a]] < X[st[b]]; });

  rep(i, sz) {
    msum += M[st[ord[i]]];
    if (msum >= mmid) {
      return X[st[ord[i]]];
    }
  }
  assert(false);
  return -1;
}

ll calcy(const vector<ll> &st) {
  ll sz = st.size();
  ll mmid = 0, msum = 0;
  rep(i, sz) mmid += M[st[i]];
  mmid /= 2;

  vector<ll> ord(sz);
  rep(i, sz) ord[i] = i;
  sort(all(ord), [&](const ll &a, const ll &b) { return Y[st[a]] < Y[st[b]]; });

  rep(i, sz) {
    msum += M[st[ord[i]]];
    if (msum >= mmid) {
      return Y[st[ord[i]]];
    }
  }
  assert(false);
  return -1;
}

int main() {
  cin >> N;
  X.resize(N), Y.resize(N), M.resize(N);
  rep(i, N) cin >> X[i] >> Y[i] >> M[i];

  rep(i, N + 1) res[i] = INF;

  vector<vector<ll>> dp(1 << N, vector<ll>(N + 1, INF));
  dp[0][0] = 0;
  repl(S, 1, 1 << N) {
    vector<ll> ids;
    rep(i, N) {
      if ((S >> i) & 1) {
        ids.push_back(i);
      }
    }
    ll cx = calcx(ids);
    ll cy = calcy(ids);
    dp[S][1] = min(calcd(ids, true, cx), calcd(ids, false, cy));
    dp[S][0] = min(calcd(ids, true, 0), calcd(ids, false, 0));
  }

  rep(S, 1 << N) {
    ll bsz = bcnt(S);
    for (ll T1 = S - 1; T1 > 0; T1--) {
      T1 &= S;
      ll T2 = (S ^ T1);

      rep(i, bsz + 1) rep(j, i + 1) minch(dp[S][i], dp[T1][j] + dp[T2][i - j]);
    }
  }
  repl(i, 1, N + 1) minch(dp[(1 << N) - 1][i], dp[(1 << N) - 1][i - 1]);

  rep(i, N + 1) cout << dp[(1 << N) - 1][i] << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i, a, b) for (ll i = (ll)(a); i < (ll)(b); i++)
#define rep(i, n) repl(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x "=" << x << endl
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define maxch(x, y) x = mmax(x, y)
#define minch(x, y) x = mmin(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt __builtin_popcountll

#define INF 1e18
#define mod 1000000007

ll N;
vector<ll> X, Y, M;
ll res[20];

ll calcd(const vector<ll> &st, bool dir, ll z) {
  ll dsum = 0;
  rep(i, st.size()) {
    if (!dir) { // x
      dsum += (ll)abs(z - Y[st[i]]) * M[st[i]];
    } else { // y
      dsum += (ll)abs(z - X[st[i]]) * M[st[i]];
    }
  }
  return dsum;
}

ll calcx(const vector<ll> &st) {
  ll sz = st.size();
  ll mmid = 0, msum = 0;
  rep(i, sz) mmid += M[st[i]];
  mmid /= 2;

  vector<ll> ord(sz);
  rep(i, sz) ord[i] = i;
  sort(all(ord), [&](const ll &a, const ll &b) { return X[st[a]] < X[st[b]]; });

  rep(i, sz) {
    msum += M[st[ord[i]]];
    if (msum >= mmid) {
      return X[st[ord[i]]];
    }
  }
  assert(false);
  return -1;
}

ll calcy(const vector<ll> &st) {
  ll sz = st.size();
  ll mmid = 0, msum = 0;
  rep(i, sz) mmid += M[st[i]];
  mmid /= 2;

  vector<ll> ord(sz);
  rep(i, sz) ord[i] = i;
  sort(all(ord), [&](const ll &a, const ll &b) { return Y[st[a]] < Y[st[b]]; });

  rep(i, sz) {
    msum += M[st[ord[i]]];
    if (msum >= mmid) {
      return Y[st[ord[i]]];
    }
  }
  assert(false);
  return -1;
}

void dfs(ll i, ll j, vector<ll> &gr) {
  if (i == N) {

    ll sz = j + 1;
    vector<vector<ll>> st(sz);
    rep(k, N) { st[gr[k]].push_back(k); }

    repl(x, -1, sz) repl(y, -1, sz) {
      ll crtgnum = sz - (x != -1 ? 1 : 0) - (y != -1 ? 1 : 0);
      if ((x >= 0 && x == y) || crtgnum < 0)
        continue;

      ll dsum = 0;
      rep(k, sz) {
        if (k == x) {
          dsum += calcd(st[k], false, 0);
        } else if (k == y) {
          dsum += calcd(st[k], true, 0);
        } else {
          ll cx = calcx(st[k]);
          ll cy = calcy(st[k]);
          dsum += min(calcd(st[k], true, cx), calcd(st[k], false, cy));
        }
      }

      minch(res[crtgnum], dsum);
    }
    return;
  }

  repl(k, 0, j + 2) {
    gr[i] = k;
    if (k == j + 1) {
      dfs(i + 1, j + 1, gr);
    } else {
      dfs(i + 1, j, gr);
    }
  }
}

int main() {

  cin >> N;
  X.resize(N), Y.resize(N), M.resize(N);
  rep(i, N) cin >> X[i] >> Y[i] >> M[i];

  vector<ll> gr(N, -1);
  rep(i, N + 1) res[i] = INF;
  dfs(0, -1, gr);
  rep(i, N + 1) cout << res[i] << endl;

  return 0;
}