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

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> pint;
typedef pair<ll, ll> pll;

#define debug(x) cout << #x << " = " << (x) << endl;
#define rep(i, n) for (int i = 0; i < n; i++)
#define repr(i, n) for (int i = n - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define F first
#define S second

const long double pi = 3.141592653589793;
const int mod = 1e9 + 7;

ll dp1[1 << 15][15], dp2[1 << 15][15], ans[16];
int X[15], Y[15], P[15], N;

int main() {

  // freopen("input.in","r",stdin);
  // freopen("output.out","w",stdout);

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  cin >> N;
  rep(i, N) cin >> X[i] >> Y[i] >> P[i];
  rep(i, 1 << N) {
    rep(j, N) {
      ll ans = 1e15;
      ll ans2 = 1e15;
      rep(k, N) {
        if (i & (1 << k)) {
          ans = min(ans, abs(X[j] - X[k]) * 1LL * P[j]);
          ans2 = min(ans2, abs(Y[j] - Y[k]) * 1LL * P[j]);
        }
      }
      dp1[i][j] = min(ans, abs(X[j]) * 1LL * P[j]);
      dp2[i][j] = min(ans2, abs(Y[j]) * 1LL * P[j]);
    }
  }

  rep(i, N + 1) ans[i] = 1e15;
  rep(i, 1 << N) {
    int cnt = 0, ii = i;
    while (ii != 0) {
      cnt += (ii & 1);
      ii >>= 1;
    }
    for (int j = i; j >= 0; j--) {
      j = j & i;
      ll ans1 = 0;
      rep(k, N) { ans1 += min(dp1[i ^ j][k], dp2[j][k]); }
      ans[cnt] = min(ans[cnt], ans1);
    }
  }

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

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define debug(x) cout << #x << " = " << (x) << endl;
#define rep(i, n) for (int i = 0; i < n; i++)
#define repr(i, n) for (int i = n - 1; i >= 0; i--)
#define pb push_back
#define mp make_pair
#define F first
#define S second

const long double pi = 3.141592653589793;
const int mod = 1e9 + 7;

const ll INF = 1e15;
ll dp1[1 << 16][20], dp2[1 << 16][20], ans[20];

int X[20], Y[20], P[20], N, j = 0;
int lookup[1 << 20];

ll solver(vector<pii> &V, vector<int> &B) {
  ll ans = 0;
  int sv = V.size();
  int sb = B.size();

  if (sb == 0) {
    rep(i, sv) { ans += abs(V[i].F) * 1LL * V[i].S; }
    return ans;
  }

  int j = 0;
  rep(i, sv) {
    if (i <= B[j]) {
      ll a = abs(V[i].F) * 1LL * V[i].S;
      ll b = abs(V[i].F - V[B[j]].F) * 1LL * V[i].S;
      ll c = INF;
      if (j != 0)
        c = abs(V[i].F - V[B[j - 1]].F) * 1LL * V[i].S;
      ans += min(a, min(b, c));
    } else if (j + 1 < sb) {
      j += 1;
      i -= 1;
    } else {
      ll a = abs(V[i].F) * 1LL * V[i].S;
      ll b = abs(V[i].F - V[B[j]].F) * 1LL * V[i].S;
      ans += min(a, min(b, INF));
    }
  }

  // for(auto x: V)cout << "(" << x.F << "," << x.S << ") ";cout<<endl;
  // for(auto x: B)cout << x << " ";cout<<endl;
  // debug(ans);

  return ans;
}

void solve(int zx) {
  // j = # of points not on either x = 0 or y = 0
  for (int mask = 0; mask < (1 << j); mask++) {

    vector<int> A;
    for (int i = 0; i < j; i++) {
      if (mask & (1 << i)) {
        A.pb(i);
      }
    }
    // sort A by X
    sort(A.begin(), A.end(),
         [](const int &u, const int &v) { return X[u] < X[v]; });

    vector<pii> vA;
    for (int i = 0; i < A.size(); i++) {
      if (i == 0)
        vA.pb({X[A[i]], P[A[i]]});
      else if (X[A[i]] == X[A[i - 1]]) {
        int j = vA.size();
        vA[j - 1].S += P[A[i]];
      } else {
        vA.pb({X[A[i]], P[A[i]]});
      }
    }

    int vs = vA.size();
    rep(i, 1 << vs) {
      vector<int> B;
      for (int l = 0; l < vs; l++) {
        if (i & (1 << l)) {
          B.pb(l);
        }
      }
      if (zx == 1)
        dp1[mask][B.size()] = min(dp1[mask][B.size()], solver(vA, B));
      else
        dp2[mask][B.size()] = min(dp2[mask][B.size()], solver(vA, B));
    }
  }
}

int main() {

  // freopen("input.in","r",stdin);
  // freopen("output.out","w",stdout);

  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  cin >> N;
  rep(i, N) {
    cin >> X[j] >> Y[j] >> P[j];
    if (X[j] == 0 || Y[j] == 0)
      j--;
    j++;
  }

  for (int mask = 0; mask < (1 << j); mask++) {
    int tmask = mask;
    for (int i = 0; tmask; i++) {
      dp1[mask][i] = dp2[mask][i] = INF;
      tmask = tmask & (tmask - 1);
    }
  }
  rep(i, N + 1) ans[i] = INF;

  solve(1);
  swap(X, Y);
  solve(2);

  // for(int i = 0;i < 10;i++) {
  //   cout<<dp1[31][i]<<" ";
  // }cout<<endl;

  for (int mask = 0; mask < (1 << j); mask++) {
    int mask2 = mask ^ ((1 << j) - 1);
    for (int i = 0; i <= N; i++)
      for (int k = 0; i + k <= N; k++)
        ans[i + k] = min(ans[i + k], dp1[mask][i] + dp2[mask2][k]);
  }

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

  return 0;
}