Problem p03806 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>

#define FOR(k, m, n) for (int(k) = (m); (k) < (n); (k)++)
#define REP(i, n) FOR((i), 0, (n))
#define ll long long
#define CLR(a) memset((a), 0, sizeof(a))
#define SZ(x) (int((x).size()))
#define WAITING(str)                                                           \
  int str;                                                                     \
  std::cin >> str;
#define DEBUGING(str) cout << str << endl
using namespace std;

const ll MOD = 1000000007; // 10^9+7
const int INF = (1ll << 30);

// 変数
int N, Ma, Mb;
vector<vector<int>> l, r;
int suma = 0;

// サブ関数
// 入力
void input() {
  cin >> N >> Ma >> Mb;
  int rcnt = min(N / 2, 15);
  l.resize(N - rcnt, vector<int>(3));
  r.resize(rcnt, vector<int>(3));
  REP(i, N - rcnt) REP(j, 3) cin >> l[i][j];
  REP(i, rcnt) REP(j, 3) cin >> r[i][j];

  if (Ma < Mb) {
    swap(Ma, Mb);
    for (auto &row : l)
      swap(row[0], row[1]);
    for (auto &row : r)
      swap(row[0], row[1]);
  }

  for (const auto &row : l)
    suma += row[0];
  for (const auto &row : r)
    suma += row[0];
}

vector<int> bit2value(const vector<vector<int>> &obj, const int i) {
  const int N = obj.size();
  int a = 0;
  int b = 0;
  int c = 0;

  REP(j, N) if (i & (1 << j)) {
    a += obj[j][0];
    b += obj[j][1];
    c += obj[j][2];
  }
  return {a, b, c};
}

map<int, map<int, int>> make_half(const vector<vector<int>> &obj) {
  const int N = obj.size();
  map<int, map<int, int>> res;

  REP(i, 1 << N) {
    auto sum = bit2value(obj, i);
    int a = sum[0];
    int b = sum[1];
    int c = sum[2];

    if (res[a].find(b) == res[a].end()) {
      res[a][b] = c;
    } else {
      res[a][b] = min(res[a][b], c);
    }
  }
  return res;
}

int find_pair(map<int, map<int, int>> &other, const vector<int> &sum) {
  int cost = INF;
  int a = sum[0];
  int b = sum[1];
  int c = sum[2];
  FOR(times, 1, suma / Ma + 1) {
    ll obja = Ma * times;
    ll objb = Mb * times;
    ll resta = obja - a;
    ll restb = objb - b;
    if (resta < 0)
      continue;
    if (restb < 0)
      continue;

    // if (other.find(resta) == other.end())continue;
    if (other[resta].find(restb) == other[resta].end())
      continue;
    cost = min(cost, other[resta][restb]);
  }
  return cost + c;
}

// 計算
void calc() {
  int cost = INF;
  int rsiz = r.size();
  auto lhalf = make_half(l);

  REP(i, 1 << rsiz) {
    auto sum = bit2value(r, i);
    if (sum[2] > cost)
      continue;
    auto bestCost = find_pair(lhalf, sum);
    cost = min(cost, bestCost);
  }

  cout << (cost == INF ? -1 : cost) << endl;
}

// 出力
void output() {}

// デバッグ
void debug() {
  int N;
  cin >> N;
}

// メイン関数
int main() {
  input();
  calc();
  output();
  debug();

  return 0;
}


Fixed submission:
#include <algorithm>
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>

#define FOR(k, m, n) for (int(k) = (m); (k) < (n); (k)++)
#define REP(i, n) FOR((i), 0, (n))
#define ll long long
#define CLR(a) memset((a), 0, sizeof(a))
#define SZ(x) (int((x).size()))
#define WAITING(str)                                                           \
  int str;                                                                     \
  std::cin >> str;
#define DEBUGING(str) cout << str << endl
using namespace std;

const ll MOD = 1000000007; // 10^9+7
const int INF = (1ll << 30);

// 変数
int N, Ma, Mb;
vector<vector<int>> l, r;
int suma = 0;

// サブ関数
// 入力
void input() {
  cin >> N >> Ma >> Mb;
  int rcnt = min(N / 2, 19);
  l.resize(N - rcnt, vector<int>(3));
  r.resize(rcnt, vector<int>(3));
  REP(i, N - rcnt) REP(j, 3) cin >> l[i][j];
  REP(i, rcnt) REP(j, 3) cin >> r[i][j];

  if (Ma < Mb) {
    swap(Ma, Mb);
    for (auto &row : l)
      swap(row[0], row[1]);
    for (auto &row : r)
      swap(row[0], row[1]);
  }

  for (const auto &row : l)
    suma += row[0];
  for (const auto &row : r)
    suma += row[0];
}

vector<int> bit2value(const vector<vector<int>> &obj, const int i) {
  const int N = obj.size();
  int a = 0;
  int b = 0;
  int c = 0;

  REP(j, N) if (i & (1 << j)) {
    a += obj[j][0];
    b += obj[j][1];
    c += obj[j][2];
  }
  return {a, b, c};
}

map<int, map<int, int>> make_half(const vector<vector<int>> &obj) {
  const int N = obj.size();
  map<int, map<int, int>> res;

  REP(i, 1 << N) {
    auto sum = bit2value(obj, i);
    int a = sum[0];
    int b = sum[1];
    int c = sum[2];

    if (res[a].find(b) == res[a].end()) {
      res[a][b] = c;
    } else {
      res[a][b] = min(res[a][b], c);
    }
  }
  return res;
}

int find_pair(map<int, map<int, int>> &other, const vector<int> &sum) {
  int cost = INF;
  int a = sum[0];
  int b = sum[1];
  int c = sum[2];
  FOR(times, 1, suma / Ma + 1) {
    ll obja = Ma * times;
    ll objb = Mb * times;
    ll resta = obja - a;
    ll restb = objb - b;
    if (resta < 0)
      continue;
    if (restb < 0)
      continue;

    // if (other.find(resta) == other.end())continue;
    if (other[resta].find(restb) == other[resta].end())
      continue;
    cost = min(cost, other[resta][restb]);
  }
  return cost + c;
}

// 計算
void calc() {
  int cost = INF;
  int rsiz = r.size();
  auto lhalf = make_half(l);

  REP(i, 1 << rsiz) {
    auto sum = bit2value(r, i);
    if (sum[2] > cost)
      continue;
    auto bestCost = find_pair(lhalf, sum);
    cost = min(cost, bestCost);
  }

  cout << (cost == INF ? -1 : cost) << endl;
}

// 出力
void output() {}

// デバッグ
void debug() {
  int N;
  cin >> N;
}

// メイン関数
int main() {
  input();
  calc();
  output();
  debug();

  return 0;
}