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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int N;
long long int X[20], Y[20], P[20];

long long int dp[1 << 17][20];

long long int INF = (long long int)1e18 - 1;

long long int val[1 << 17]; // 集合Sを決めたときの最小値

int s_val[16000000], t_val[16000000];

int used_X[20], used_Y[20];

int main(void) {

  cin >> N;
  for (int i = 1; i <= N; i++) {
    cin >> X[i] >> Y[i] >> P[i];
  }

  for (int i = 0; i < (1 << N); i++) {
    for (int k = 0; k <= N; k++) {
      dp[i][k] = INF;
    }
  }

  int M = pow(3, N);

  for (int k = 0; k < M; k++) {
    int tmp = k;
    int b = 0;
    // vector<long long int> VX, VY;
    for (int i = 1; i <= N; i++) {
      used_X[i] = 0;
      used_Y[i] = 0;
    }

    long long int sum = 0;

    int pos = 1;
    for (int i = 1; i <= N; i++) {
      b *= 2;
      if (tmp % 3 == 1) { /* VX.push_back(pos);*/
        sum += abs(X[i]) * P[i];
        b++;
      } else if (tmp % 3 == 2) { /*VY.push_back(pos);*/
        sum += abs(Y[i]) * P[i];
        b++;
      }
      tmp /= 3;
      pos++;
    }

    /*for (auto u : VX) {  sum += abs(X[u])*P[u]; }
    for (auto u : VY) { sum += abs(Y[u])*P[u]; }*/
    dp[b][0] = min(dp[b][0], sum);
  }

  for (int k = 0; k < (1 << N); k++) {
    val[k] = INF;
  }

  for (int k = 0; k < (1 << N); k++) {
    for (int u = 1; u <= N; u++) {
      long long int tmp = 0;
      for (int i = 1; i <= N; i++) {
        if (k & (1 << (N - i))) {
          tmp += abs(X[i] - X[u]) * P[i];
        }
      }
      val[k] = min(val[k], tmp);
    }
    for (int u = 1; u <= N; u++) {
      long long int tmp = 0;
      for (int i = 1; i <= N; i++) {
        if (k & (1 << (N - i))) {
          tmp += abs(Y[i] - Y[u]) * P[i];
        }
      }
      val[k] = min(val[k], tmp);
    }
  }

  for (int m = 0; m < M; m++) {
    int tmp = m;
    int tmp_s = 0;
    int tmp_t = 0;
    for (int i = 1; i <= N; i++) {
      tmp_s *= 2;
      tmp_t *= 2;
      if (tmp % 3 == 1) {
        tmp_s++;
      } else if (tmp % 3 == 2) {
        tmp_t++;
      }
      tmp /= 3;
    }
    s_val[m] = tmp_s;
    t_val[m] = tmp_t;
  }

  for (int k = 1; k <= N; k++) {
    for (int m = 0; m < M; m++) {
      int s = s_val[m];
      int t = t_val[m];
      dp[s | t][k] = min(dp[s | t][k], dp[s][k - 1] + val[t]);
    }
  }

  for (int k = 0; k <= N; k++) {
    cout << dp[(1 << N) - 1][k] << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int N;
long long int X[20], Y[20], P[20];

long long int dp[1 << 17][20];

long long int INF = (long long int)1e18 - 1;

long long int val[1 << 17]; // 集合Sを決めたときの最小値

int s_val[16000000], t_val[16000000];

int main(void) {

  cin >> N;
  for (int i = 1; i <= N; i++) {
    cin >> X[i] >> Y[i] >> P[i];
  }

  for (int i = 0; i < (1 << N); i++) {
    for (int k = 0; k <= N; k++) {
      dp[i][k] = INF;
    }
  }

  int M = pow(3, N);

  for (int k = 0; k < M; k++) {
    int tmp = k;
    int b = 0;
    vector<long long int> VX, VY;
    int pos = 1;
    for (int i = 0; i < N; i++) {
      b *= 2;
      if (tmp % 3 == 1) {
        VX.push_back(pos);
        b++;
      } else if (tmp % 3 == 2) {
        VY.push_back(pos);
        b++;
      }
      tmp /= 3;
      pos++;
    }
    /*cout << "b= " << bitset<3>(b) << endl;
    cout << "VX: "; for (auto x : VX) { cout << " " << x; }cout << endl;
    cout << "VY: "; for (auto y : VY) { cout << " " << y; }cout << endl;*/
    long long int sum = 0;
    for (auto u : VX) {
      sum += abs(X[u]) * P[u];
    }
    for (auto u : VY) {
      sum += abs(Y[u]) * P[u];
    }
    dp[b][0] = min(dp[b][0], sum);
  }

  for (int k = 0; k < (1 << N); k++) {
    val[k] = INF;
  }

  for (int k = 0; k < (1 << N); k++) {
    for (int u = 1; u <= N; u++) {
      long long int tmp = 0;
      for (int i = 1; i <= N; i++) {
        if (k & (1 << (N - i))) {
          tmp += abs(X[i] - X[u]) * P[i];
        }
      }
      val[k] = min(val[k], tmp);
    }
    for (int u = 1; u <= N; u++) {
      long long int tmp = 0;
      for (int i = 1; i <= N; i++) {
        if (k & (1 << (N - i))) {
          tmp += abs(Y[i] - Y[u]) * P[i];
        }
      }
      val[k] = min(val[k], tmp);
    }
  }

  /*for (int k = 0; k < (1 << N); k++) {
          cout << "val[" << bitset<3>(k) << "]= " << val[k] << endl;
  }*/

  for (int m = 0; m < M; m++) {
    int tmp = m;
    int tmp_s = 0;
    int tmp_t = 0;
    for (int i = 1; i <= N; i++) {
      tmp_s *= 2;
      tmp_t *= 2;
      if (tmp % 3 == 1) {
        tmp_s++;
      } else if (tmp % 3 == 2) {
        tmp_t++;
      }
      tmp /= 3;
    }
    s_val[m] = tmp_s;
    t_val[m] = tmp_t;
  }

  for (int k = 1; k <= N; k++) {
    for (int m = 0; m < M; m++) {
      int s = s_val[m];
      int t = t_val[m];
      dp[s | t][k] = min(dp[s | t][k], dp[s][k - 1] + val[t]);
    }
  }

  for (int k = 0; k <= N; k++) {
    cout << dp[(1 << N) - 1][k] << endl;
  }

  return 0;
}