Problem p03806 (C++)

Buggy submission (status: Runtime Error):
/*~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
*$* WRITER:kakitamasziru/OxOmisosiru *$*
~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=*/
#ifdef LOCAL_JUDGE
#define _GLIBCXX_DEBUG
#endif
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <bitset>    // bitset
#include <cmath>     //abs,,,
#include <cstdint>   // int64_t, int*_t
#include <deque>     // deque
#include <iostream>  // cout, endl, cin
#include <limits>    //setprecision
#include <map>       // map
#include <math.h>    //pow,,,
#include <numeric>   //accumulate,,,
#include <queue>     // queue, priority_queue
#include <set>       // set,multiset
#include <stack>     // stack
#include <string>    // string, to_string, stoi
#include <tuple>     // tuple, make_tuple
#include <utility>   // pair, make_pair
#include <vector>    // vector
#define endl "\n";
using namespace std;

const long long INF = 4000000000000000001;
const int inf = 1001001001;
const int MOD = 1000000007;
typedef pair<long long, long long> P;

void chmax(long long &a, long long b) {
  if (a < b)
    a = b;
}
void chmin(long long &a, long long b) {
  if (a > b)
    a = b;
}

// Solve N^M. This, mod_pow use Iterative Square Method.
long long mod_pow(long long N, long long M) {
  if (M == 0)
    return 1;
  long long res = mod_pow((N * N) % MOD, M / 2);
  // When end-of-a bit is 1, times simple N.
  if (M & 1)
    res = (res * N) % MOD;
  return res %= MOD;
}
long long gcd(long long a, long long b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }

// dp[i][j][k]:i個目までを選んだ時、aをjグラム、bをkグラムちょうど含む金額の最小値
int dp[45][405][405];

int main() {
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);

  int N, M, K;
  cin >> N >> M >> K;
  for (int i = 0; i < 45; i++)
    for (int j = 0; j < 405; j++)
      for (int k = 0; k < 405; k++)
        dp[i][j][k] = inf;
  dp[0][0][0] = 0;

  for (int i = 0; i < N; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    for (int j = 0; j < 405; j++) {
      for (int k = 0; k < 405; k++) {
        if (dp[i][j][k] == inf)
          continue;
        dp[i + 1][j + a][k + b] = min(dp[i][j][k] + c, dp[i + 1][j + a][k + b]);
        dp[i + 1][j][k] = min(dp[i + 1][j][k], dp[i][j][k]);
      }
    }
  }

  /*for(int i = 0;i<=N;i++){
      for(int j = 0;j<=3;j++){
          for(int k = 0;k<=3;k++){
              cout << dp[i][j][k] << " ";
          }
      }
      cout << endl;
  }*/

  int ans = inf;
  for (int i = 1; i < 405; i++) {
    int ratioA = M, ratioB = K;
    ratioA *= i, ratioB *= i;
    ans = min(ans, dp[N][ratioA][ratioB]);
  }
  if (ans == inf) {
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }
}


Fixed submission:
/*~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=
*$* WRITER:kakitamasziru/OxOmisosiru *$*
~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=*/
#ifdef LOCAL_JUDGE
#define _GLIBCXX_DEBUG
#endif
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <bitset>    // bitset
#include <cmath>     //abs,,,
#include <cstdint>   // int64_t, int*_t
#include <deque>     // deque
#include <iostream>  // cout, endl, cin
#include <limits>    //setprecision
#include <map>       // map
#include <math.h>    //pow,,,
#include <numeric>   //accumulate,,,
#include <queue>     // queue, priority_queue
#include <set>       // set,multiset
#include <stack>     // stack
#include <string>    // string, to_string, stoi
#include <tuple>     // tuple, make_tuple
#include <utility>   // pair, make_pair
#include <vector>    // vector
#define endl "\n";
using namespace std;

const long long INF = 4000000000000000001;
const int inf = 1001001001;
const int MOD = 1000000007;
typedef pair<long long, long long> P;

void chmax(long long &a, long long b) {
  if (a < b)
    a = b;
}
void chmin(long long &a, long long b) {
  if (a > b)
    a = b;
}

// Solve N^M. This, mod_pow use Iterative Square Method.
long long mod_pow(long long N, long long M) {
  if (M == 0)
    return 1;
  long long res = mod_pow((N * N) % MOD, M / 2);
  // When end-of-a bit is 1, times simple N.
  if (M & 1)
    res = (res * N) % MOD;
  return res %= MOD;
}
long long gcd(long long a, long long b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }

// dp[i][j][k]:i個目までを選んだ時、aをjグラム、bをkグラムちょうど含む金額の最小値
int dp[45][405][405];

int main() {
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);

  int N, M, K;
  cin >> N >> M >> K;
  for (int i = 0; i < 45; i++)
    for (int j = 0; j < 405; j++)
      for (int k = 0; k < 405; k++)
        dp[i][j][k] = inf;
  dp[0][0][0] = 0;

  for (int i = 0; i < N; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    for (int j = 0; j < 405; j++) {
      for (int k = 0; k < 405; k++) {
        if (dp[i][j][k] == inf)
          continue;
        dp[i + 1][j + a][k + b] = min(dp[i][j][k] + c, dp[i + 1][j + a][k + b]);
        dp[i + 1][j][k] = min(dp[i + 1][j][k], dp[i][j][k]);
      }
    }
  }

  /*for(int i = 0;i<=N;i++){
      for(int j = 0;j<=3;j++){
          for(int k = 0;k<=3;k++){
              cout << dp[i][j][k] << " ";
          }
      }
      cout << endl;
  }*/

  int ans = inf;
  for (int i = 1; i < 405; i++) {
    int ratioA = M, ratioB = K;
    ratioA *= i, ratioB *= i;
    if (ratioA > 400 || ratioB > 400)
      break;
    ans = min(ans, dp[N][ratioA][ratioB]);
  }
  if (ans == inf) {
    cout << -1 << endl;
  } else {
    cout << ans << endl;
  }
}