Problem p03806 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <climits>
#include <iostream>
#include <list>
#include <queue>
#include <string>
#include <vector>
#define int long long
#define uint unsigned long long
#define CONTAINS(v, n) (find((v).begin(), (v).end(), (n)) != (v).end())
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
using namespace std;

int n, ma, mb;
int yaku_a[40];
int yaku_b[40];
int yaku_c[40];
int init = 1145141919810;
int inf = 1145141919;
int memo[41][400][400];

int func(int num, int a,
         int b) // num番目まで来たときの割合がa,bだったときの最小コスト
{
  if (a < 0 || b < 0) {
    return inf;
  }
  if (memo[num][a][b] < init) {
    return memo[num][a][b];
  }
  if (num == 0) {
    if (a == 0 && b == 0)
      return 0;
    else
      return inf;
  }

  int ya = yaku_a[num - 1];
  int yb = yaku_b[num - 1];
  int yc = yaku_c[num - 1];
  int val1 = func(num - 1, a, b);
  int val2 = func(num - 1, a - ya, b - yb) + yc;
  return MIN(val1, val2);
}

signed main() {
  for (int i = 0; i <= 40; i++) {
    for (int a = 0; a < 400; a++) {
      for (int b = 0; b < 400; b++) {
        memo[i][a][b] = init;
      }
    }
  }

  cin >> n >> ma >> mb;
  for (int i = 0; i < n; i++) {
    cin >> yaku_a[i] >> yaku_b[i] >> yaku_c[i];
  }

  int min_val = init;
  for (int a = 1; a < 400; a++) {
    for (int b = 1; b < 400; b++) {
      if (ma * b == a * mb) {
        int val = func(n, a, b);
        if (val < min_val) {
          min_val = val;
        }
      }
    }
  }

  if (min_val < inf) {
    cout << min_val << endl;
  } else {
    cout << -1 << endl;
  }
}


Fixed submission:
#include <algorithm>
#include <climits>
#include <iostream>
#include <list>
#include <queue>
#include <string>
#include <vector>
#define int long long
#define uint unsigned long long
#define CONTAINS(v, n) (find((v).begin(), (v).end(), (n)) != (v).end())
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
using namespace std;

int n, ma, mb;
int yaku_a[40];
int yaku_b[40];
int yaku_c[40];
int init = 1145141919810;
int inf = 1145141919;
int memo[41][400][400];

int func(int num, int a,
         int b) // num番目まで来たときの割合がa,bだったときの最小コスト
{
  if (a < 0 || b < 0) {
    return inf;
  }
  if (memo[num][a][b] < init) {
    return memo[num][a][b];
  }
  if (num == 0) {
    if (a == 0 && b == 0)
      return 0;
    else
      return inf;
  }

  int ya = yaku_a[num - 1];
  int yb = yaku_b[num - 1];
  int yc = yaku_c[num - 1];
  int val1 = func(num - 1, a, b);
  int val2 = func(num - 1, a - ya, b - yb) + yc;
  return memo[num][a][b] = MIN(val1, val2);
}

signed main() {
  for (int i = 0; i <= 40; i++) {
    for (int a = 0; a < 400; a++) {
      for (int b = 0; b < 400; b++) {
        memo[i][a][b] = init;
      }
    }
  }

  cin >> n >> ma >> mb;
  for (int i = 0; i < n; i++) {
    cin >> yaku_a[i] >> yaku_b[i] >> yaku_c[i];
  }

  int min_val = init;
  for (int a = 1; a < 400; a++) {
    for (int b = 1; b < 400; b++) {
      if (ma * b == a * mb) {
        int val = func(n, a, b);
        if (val < min_val) {
          min_val = val;
        }
      }
    }
  }

  if (min_val < inf) {
    cout << min_val << endl;
  } else {
    cout << -1 << endl;
  }
}