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

#include <bits/stdc++.h>
#define maxn 17

using namespace std;

typedef long long ll;

int n;
int x[maxn], y[maxn], p[maxn];
int xx[maxn], yy[maxn];
int xxx[1 << maxn][maxn], yyy[1 << maxn][maxn];
ll ans[maxn];

int a[maxn], b[maxn];
int mn = maxn;

inline bool cmp1(int i, int j) { return x[i] < x[j]; }

inline bool cmp2(int i, int j) { return y[i] < y[j]; }

int main() {
  scanf("%d", &n);
  for (register int i = 1; i <= n; i++)
    scanf("%d%d%d", &x[i], &y[i], &p[i]), xx[i] = i, yy[i] = i;
  sort(xx + 1, xx + 1 + n, cmp1);
  sort(yy + 1, yy + 1 + n, cmp2);
  for (register int i = (1 << n) - 1; ~i; i--) {
    for (register int j = 1; j <= n; j++) {
      if (!(i & (1 << (j - 1))))
        xxx[i][j] = yyy[i][j] = min(abs(x[j]), abs(y[j]));
    }
    int k = 0;
    for (register int j = 1; j <= n; j++) {
      if (i & (1 << (xx[j] - 1)))
        k = j;
      else if (k)
        xxx[i][xx[j]] = min(xxx[i][xx[j]], x[xx[j]] - x[xx[k]]);
    }
    k = 0;
    for (register int j = n; j; j--) {
      if (i & (1 << (xx[j] - 1)))
        k = j;
      else if (k)
        xxx[i][xx[j]] = min(xxx[i][xx[j]], x[xx[k]] - x[xx[j]]);
    }
    k = 0;
    for (register int j = 1; j <= n; j++) {
      if (i & (1 << (yy[j] - 1)))
        k = j;
      else if (k)
        yyy[i][yy[j]] = min(yyy[i][yy[j]], y[yy[j]] - y[yy[k]]);
    }
    k = 0;
    for (register int j = n; j; j--) {
      if (i & (1 << (yy[j] - 1)))
        k = j;
      else if (k)
        yyy[i][yy[j]] = min(yyy[i][yy[j]], y[yy[k]] - y[yy[j]]);
    }
  }
  int sup = (int)pow(3, n) - 1;
  memset(ans, 0x3f, sizeof(ans));
  for (register int i = 0; i <= sup; i++) {
    memset(a, 0, sizeof(a));
    register int cnt = 0, xbit = 0, ybit = 0;
    for (register int j = i, k = 1; j; k++) {
      a[k] = j % 3, j /= 3;
      if (a[k] == 1)
        xbit += 1 << (k - 1), cnt++;
      else if (a[k] == 2)
        ybit += 1 << (k - 1), cnt++;
    }
    if (cnt >= mn) {
      ans[cnt] = 0;
      continue;
    }
    /*for(register int j = 1;j <= n;j++){
            if(!a[j]) b[j] = min(abs(x[j]), abs(y[j]));
            //else b[j] = 0;
    }
    int k = 0;
    for(register int j = 1;j <= n;j++){
            if(a[xx[j]] == 1) k = j;
            else if(!a[xx[j]] && k) b[xx[j]] = min(b[xx[j]], x[xx[j]] -
    x[xx[k]]);
    }
    k = 0;
    for(register int j = n;j;j--){
            if(a[xx[j]] == 1) k = j;
            else if(!a[xx[j]] && k) b[xx[j]] = min(b[xx[j]], x[xx[k]] -
    x[xx[j]]);
    }
    k = 0;
    for(register int j = 1;j <= n;j++){
            if(a[yy[j]] == 2) k = j;
            else if(!a[yy[j]] && k) b[yy[j]] = min(b[yy[j]], y[yy[j]] -
    y[yy[k]]);
    }
    k = 0;
    for(register int j = n;j;j--){
            if(a[yy[j]] == 2) k = j;
            else if(!a[yy[j]] && k) b[yy[j]] = min(b[yy[j]], y[yy[k]] -
    y[yy[j]]);
    }*/
    register ll sum = 0;
    for (register int j = 1; j <= n; j++)
      if (!a[j])
        sum += 1ll * p[j] * min(xxx[xbit][j], yyy[ybit][j]);
    ans[cnt] = min(ans[cnt], sum);
    if (ans[cnt] == 0)
      mn = min(mn, cnt);
  }
  for (register int i = 0; i <= n; i++)
    printf("%lld\\n", ans[i]);
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define maxn 17

using namespace std;

typedef long long ll;

int n;
int x[maxn], y[maxn], p[maxn];
int xx[maxn], yy[maxn];
ll ans[maxn];
set<int> X, Y;
int a[maxn], b[maxn];
int mn = maxn;

inline bool cmp1(int i, int j) { return x[i] < x[j]; }

inline bool cmp2(int i, int j) { return y[i] < y[j]; }

int main() {
  scanf("%d", &n);
  for (register int i = 1; i <= n; i++)
    scanf("%d%d%d", &x[i], &y[i], &p[i]), xx[i] = i, yy[i] = i;
  sort(xx + 1, xx + 1 + n, cmp1);
  sort(yy + 1, yy + 1 + n, cmp2);
  int sup = (int)pow(3, n) - 1;
  memset(ans, 0x3f, sizeof(ans));
  for (register int i = 0; i <= sup; i++) {
    memset(a, 0, sizeof(a));
    register int cnt = 0;
    for (register int j = i, k = 1; j; k++) {
      a[k] = j % 3, j /= 3;
      if (a[k])
        cnt++;
    }
    if (cnt >= mn) {
      ans[cnt] = 0;
      continue;
    }
    register ll sum = 0;
    for (register int j = 1; j <= n; j++) {
      if (!a[j])
        b[j] = min(abs(x[j]), abs(y[j]));
      else
        b[j] = 0;
    }
    int k = 0;
    for (register int j = 1; j <= n; j++) {
      if (a[xx[j]] == 1)
        k = j;
      if (!a[xx[j]] && k)
        b[xx[j]] = min(b[xx[j]], x[xx[j]] - x[xx[k]]);
    }
    k = 0;
    for (register int j = n; j; j--) {
      if (a[xx[j]] == 1)
        k = j;
      if (!a[xx[j]] && k)
        b[xx[j]] = min(b[xx[j]], x[xx[k]] - x[xx[j]]);
    }
    k = 0;
    for (register int j = 1; j <= n; j++) {
      if (a[yy[j]] == 2)
        k = j;
      if (!a[yy[j]] && k)
        b[yy[j]] = min(b[yy[j]], y[yy[j]] - y[yy[k]]);
    }
    k = 0;
    for (register int j = n; j; j--) {
      if (a[yy[j]] == 2)
        k = j;
      if (!a[yy[j]] && k)
        b[yy[j]] = min(b[yy[j]], y[yy[k]] - y[yy[j]]);
    }
    for (register int j = 1; j <= n; j++)
      sum += 1ll * p[j] * b[j];
    /*X.clear(), Y.clear();
    X.insert(0), Y.insert(0), X.insert(-1e9), Y.insert(-1e9);
    bool tag = false;
    for(register int j = 1;j <= n;j++){
            if(a[j] == 1){
                    if(!X.insert(x[j]).second){
                            tag = true;
                            break;
                    }
            }
            else if(a[j] == 2){
                    if(!Y.insert(y[j]).second){
                            tag = true;
                            break;
                    }
            }

    }
    if(tag) continue;
    register ll sum = 0;
    for(register int j = 1;j <= n;j++){
            if(a[j]) continue;
            int dis = 1e4;
            set<int>::iterator it = X.lower_bound(x[j]);
            if(it != X.end()) dis = min(dis, abs(*it - x[j]));
            dis = min(dis, abs(*prev(it) - x[j]));
            it = Y.lower_bound(y[j]);
            if(it != Y.end()) dis = min(dis, abs(*it - y[j]));
            dis = min(dis, abs(*prev(it) - y[j]));
            //printf("%d %d %d %d %d--\\n", i, j, cnt, p[j], dis);
            sum += 1ll * p[j] * dis;
    }*/
    ans[cnt] = min(ans[cnt], sum);
    if (ans[cnt] == 0)
      mn = min(mn, cnt);
  }
  for (register int i = 0; i <= n; i++)
    printf("%lld\\n", ans[i]);
}