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

/**
 * Dont raise your voice, improve your argument.
 * --Desmond Tutu
 */

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

const bool ready = []() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(12);
  return true;
}();

const double PI = acos(-1);
using ll = long long;
#define int ll
#define all(v) (v).begin(), (v).end()
#define fori(n) for (int i = 0; i < int(n); i++)

#define cini(i)                                                                \\
  int i;                                                                       \\
  cin >> i;
#define cins(s)                                                                \\
  string s;                                                                    \\
  cin >> s;
#define cind(d)                                                                \\
  double d;                                                                    \\
  cin >> d;
#define cinai(a, n)                                                            \\
  vi a(n);                                                                     \\
  fori(n) { cin >> a[i]; }
#define cinas(s, n)                                                            \\
  vs s(n);                                                                     \\
  fori(n) { cin >> s[i]; }
#define cinad(a, n)                                                            \\
  vd a(n);                                                                     \\
  fori(n) { cin >> a[i]; }

using pii = pair<int, int>;
using pdd = pair<double, double>;
using vd = vector<double>;
using vb = vector<bool>;
using vi = vector<int>;
using vvi = vector<vi>;
using vs = vector<string>;

/* Grid
 * Clock at 0,0
 * horizontal east west streets
 * vertical north south streets
 * Two initial railroads, x-axis and y-axis
 *
 * Note that points are weighted by p[i]
 * Since N is small we should be able to brute force somehow.
 *
 * Note that with n railroads ans eq 0.
 *
 * With one railroad we got basically 4
 * Building one railroad in a quadrant must be done
 * on median element (median with p[]).
 * Building secdon railroad in same quadrant...
 * ...
 * Brute force all of it.
 * All railroads should go through a position. But if a position has
 * a railroad, there is never need to build a second through it.
 *
 * So we got N positions and a horz or a vert or non railroad.
 * This is 3^n possible states.
 * Foreach one find the dist value, and update the ans for
 * number of build railroads.
 *
 * How to iterate 012? -> implement on vector
 * How to precalc the distances?
 */
const int INF = 1e18;

void solve() {
  cini(n);
  vi x(n);
  vi y(n);
  vi p(n);

  for (int i = 0; i < n; i++)
    cin >> x[i] >> y[i] >> p[i];

  vi ans(n + 1, INF);
  ans[0] = 0;
  for (int i = 0; i < n; i++)
    ans[0] += min(abs(x[i]), abs(y[i])) * p[i];

  for (int s = 0; s < (1 << n); s++) { // rails throug houses where s bit is set
    vi nobits;
    vi bits;
    for (int i = 0; i < n; i++) {
      if ((s >> i) & 1)
        bits.push_back(i);
      else
        nobits.push_back(i);
    }

    for (int t = s; true;
         t = (t - 1) & s) { // horz rail if t set else vert rail
      int dist = 0;
      for (int i : nobits) { // all houses
        int d = min(abs(x[i]), abs(y[i]));
        for (int j : bits) { // all rails
          if ((t >> j) & 1)
            d = min(d, abs(x[i] - x[j]));
          else
            d = min(d, abs(y[i] - y[j]));
        }
        dist += d * p[i];
      }
      ans[bits.size()] = min(ans[bits.size()], dist);
      if (t == 0)
        break;
    }
  }

  for (signed i = 0; i <= n; i++)
    cout << ans[i] << endl;
}

signed main() { solve(); }

// FIRST THINK, THEN CODE
// DO NOT JUMP BETWEEN PROBLEMS


Error: TLE

Fixed submission:

/**
 * Dont raise your voice, improve your argument.
 * --Desmond Tutu
 */

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

const bool ready = []() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(12);
  return true;
}();

const double PI = acos(-1);
using ll = long long;
#define int ll
#define all(v) (v).begin(), (v).end()
#define fori(n) for (int i = 0; i < int(n); i++)

#define cini(i)                                                                \\
  int i;                                                                       \\
  cin >> i;
#define cins(s)                                                                \\
  string s;                                                                    \\
  cin >> s;
#define cind(d)                                                                \\
  double d;                                                                    \\
  cin >> d;
#define cinai(a, n)                                                            \\
  vi a(n);                                                                     \\
  fori(n) { cin >> a[i]; }
#define cinas(s, n)                                                            \\
  vs s(n);                                                                     \\
  fori(n) { cin >> s[i]; }
#define cinad(a, n)                                                            \\
  vd a(n);                                                                     \\
  fori(n) { cin >> a[i]; }

using pii = pair<int, int>;
using pdd = pair<double, double>;
using vd = vector<double>;
using vb = vector<bool>;
using vi = vector<int>;
using vvi = vector<vi>;
using vs = vector<string>;

signed n;
signed a[16];
inline bool inc() {
  for (signed i = 0; i < n; i++) {
    a[i]++;
    if (a[i] == 3)
      a[i] = 0;
    else
      return true;
  }
  return false;
}

/* Grid
 * Clock at 0,0
 * horizontal east west streets
 * vertical north south streets
 * Two initial railroads, x-axis and y-axis
 *
 * Note that points are weighted by p[i]
 * Since N is small we should be able to brute force somehow.
 *
 * Note that with n railroads ans eq 0.
 *
 * With one railroad we got basically 4
 * Building one railroad in a quadrant must be done
 * on median element (median with p[]).
 * Building secdon railroad in same quadrant...
 * ...
 * Brute force all of it.
 * All railroads should go through a position. But if a position has
 * a railroad, there is never need to build a second through it.
 *
 * So we got N positions and a horz or a vert or non railroad.
 * This is 3^n possible states.
 * Foreach one find the dist value, and update the ans for
 * number of build railroads.
 *
 * How to iterate 012? -> implement on vector
 * How to precalc the distances?
 */
const int INF = 1e18;
int x[16];
int y[16];
int p[16];
int ans[17];

void solve() {
  cin >> n;

  for (int i = 0; i < n; i++)
    cin >> x[i] >> y[i] >> p[i];

  for (int i = 0; i <= n; i++)
    ans[i] = INF;

  do {
    signed cntb = 0;
    int dist = 0;
    for (signed i = 0; i < n; i++) {
      if (a[i])
        cntb++;
      else {
        int d = min(abs(x[i]), abs(y[i]));
        for (signed j = 0; j < n; j++) {
          if (a[j] == 1)
            d = min(d, abs(x[i] - x[j]));
          else if (a[j] == 2)
            d = min(d, abs(y[i] - y[j]));
        }
        dist += d * p[i];
      }
    }
    ans[cntb] = min(ans[cntb], dist);

  } while (inc());

  for (signed i = 0; i <= n; i++)
    cout << ans[i] << endl;
}

signed main() { solve(); }

// FIRST THINK, THEN CODE
// DO NOT JUMP BETWEEN PROBLEMS