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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...)                                                           \\
  do {                                                                         \\
  } while (0)
#endif
#include <cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define EACH(i, c)                                                             \\
  for (__typeof((c).begin()) i = (c).begin(), i##_end = (c).end();             \\
       i != i##_end; ++i)

template <class T> inline void amin(T &x, const T &y) {
  if (y < x)
    x = y;
}
template <class T> inline void amax(T &x, const T &y) {
  if (x < y)
    x = y;
}
template <class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
  for (bool sp = 0; begin != end; ++begin) {
    if (sp)
      putchar(' ');
    else
      sp = true;
    printf(fmt, *begin);
  }
  putchar('\\n');
}
inline int bits(int m) { return (1 << m) - 1; }
using Double = double;
const Double INF = 1e100;

int N;
LL X[15], Y[15], A[15];

Double D[15][15];
Double cst[1 << 15];
Double sum[1 << 15];
bool dp[1 << 15];

bool ok(Double mid) {
  Double need = 0;
  Double rest = 0;
  REP(i, N) {
    if (A[i] < mid) {
      need += mid - A[i];
    } else {
      rest += A[i] - mid;
    }
  }
  if (need == 0)
    return true;
  if (rest < need)
    return false;

  REP(s, 1 << N) if (s) {
    REP(i, N) if (s >> i & 1) {
      sum[s] = sum[s ^ (1 << i)] + A[i];
      break;
    }
  }

  memset(dp, 0, sizeof dp);
  dp[0] = true;
  REP(s, 1 << N) if (dp[s]) {
    int other = bits(N) ^ s;
    int sup = other & (other - 1);
    int small = sup ^ other;
    for (int t = sup;; t = (t - 1) & sup) {
      if (sum[t | small] - __builtin_popcount(t | small) * mid -
              cst[t | small] >=
          0)
        dp[s | t | small] = true;
      if (t == 0)
        break;
    }
  }

  return dp[bits(N)];
}

void MAIN() {
  scanf("%d", &N);
  REP(i, N) scanf("%lld%lld%lld", X + i, Y + i, A + i);

  REP(t, N) REP(i, N - 1) if (A[i] > A[i + 1]) {
    swap(X[i], X[i + 1]);
    swap(Y[i], Y[i + 1]);
    swap(A[i], A[i + 1]);
  }

  REP(i, N) REP(j, N) D[i][j] = hypot((Double)X[i] - X[j], (Double)Y[i] - Y[j]);
  REP(s, 1 << N) cst[s] = INF;
  REP(s, 1 << N) {
    if (__builtin_popcount(s) <= 1)
      cst[s] = 0;
    REP(i, N)
    if (s >> i & 1) REP(j, N) if (~s >> j & 1)
        amin(cst[s | 1 << j], cst[s] + D[i][j]);
  }

  Double lo = *min_element(A, A + N), hi = *max_element(A, A + N);
  REP(t, 60) {
    Double mid = (lo + hi) / 2;
    (ok(mid) ? lo : hi) = mid;
  }
  double ans = (lo + hi) / 2;
  printf("%.12f\\n", ans);
}

int main() {
  int TC = 1;
  //    scanf("%d", &TC);
  REP(tc, TC) MAIN();
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <queue>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...)                                                           \\
  do {                                                                         \\
  } while (0)
#endif
#include <cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i, n) for (int i = 0, i##_len = (n); i < i##_len; ++i)
#define EACH(i, c)                                                             \\
  for (__typeof((c).begin()) i = (c).begin(), i##_end = (c).end();             \\
       i != i##_end; ++i)

template <class T> inline void amin(T &x, const T &y) {
  if (y < x)
    x = y;
}
template <class T> inline void amax(T &x, const T &y) {
  if (x < y)
    x = y;
}
template <class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
  for (bool sp = 0; begin != end; ++begin) {
    if (sp)
      putchar(' ');
    else
      sp = true;
    printf(fmt, *begin);
  }
  putchar('\\n');
}
inline int bits(int m) { return (1 << m) - 1; }
using Double = double;
const Double INF = 1e100;

int N;
LL X[15], Y[15], A[15];

Double D[15][15];
Double cst[1 << 15];
Double sum[1 << 15];
bool dp[1 << 15];

bool ok(Double mid) {
  Double need = 0;
  Double rest = 0;
  REP(i, N) {
    if (A[i] < mid) {
      need += mid - A[i];
    } else {
      rest += A[i] - mid;
    }
  }
  if (need == 0)
    return true;
  if (rest < need)
    return false;

  REP(s, 1 << N) if (s) {
    REP(i, N) if (s >> i & 1) {
      sum[s] = sum[s ^ (1 << i)] + A[i];
      break;
    }
  }

  memset(dp, 0, sizeof dp);
  dp[0] = true;
  REP(s, 1 << N) if (dp[s]) {
    int sup = bits(N) ^ s;
    for (int t = sup; t; t = (t - 1) & sup) {
      if (sum[t] - __builtin_popcount(t) * mid - cst[t] >= 0)
        dp[s | t] = true;
    }
  }

  return dp[bits(N)];
}

void MAIN() {
  scanf("%d", &N);
  REP(i, N) scanf("%lld%lld%lld", X + i, Y + i, A + i);

  REP(t, N) REP(i, N - 1) if (A[i] > A[i + 1]) {
    swap(X[i], X[i + 1]);
    swap(Y[i], Y[i + 1]);
    swap(A[i], A[i + 1]);
  }

  REP(i, N) REP(j, N) D[i][j] = hypot((Double)X[i] - X[j], (Double)Y[i] - Y[j]);
  REP(s, 1 << N) cst[s] = INF;
  REP(s, 1 << N) {
    if (__builtin_popcount(s) <= 1)
      cst[s] = 0;
    REP(i, N)
    if (s >> i & 1) REP(j, N) if (~s >> j & 1)
        amin(cst[s | 1 << j], cst[s] + D[i][j]);
  }

  Double lo = *min_element(A, A + N), hi = *max_element(A, A + N);
  REP(t, 60) {
    Double mid = (lo + hi) / 2;
    (ok(mid) ? lo : hi) = mid;
  }
  double ans = (lo + hi) / 2;
  printf("%.12f\\n", ans);
}

int main() {
  int TC = 1;
  //    scanf("%d", &TC);
  REP(tc, TC) MAIN();
  return 0;
}