Problem p02787 (C++)

Buggy submission (status: Time Limit Exceeded):
// #include <ext/pb_ds/assoc_container.hpp>
//  #include <ext/pb_ds/tree_policy.hpp>
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>
using namespace std;
#define IOS                                                                    \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
#define trace(x) cerr << #x << ": " << x << " " << endl;

typedef int64_t ll;

#define endl '\n'
#define int ll
ll mod = 1e17;
ll mod1 = 1e9 + 5;

ll power(ll a, ll b) {
  if (b == 0)
    return 1;
  else if (b % 2 == 0)
    return power((((a % mod) * (a % mod)) % mod), b / 2) % mod;
  else
    return ((a % mod) * (power((((a % mod) * (a % mod)) % mod), b / 2) % mod)) %
           mod;
}

// using namespace __gnu_pbds;
// #define ordered_set tree<pair<int,int>, null_type,less<pair<int,int>>,
// rb_tree_tag,tree_order_statistics_node_update>
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;
// erase,insert same as normal set
int h, n;
pair<int, int> p[1000 + 1];
int dp[20001][1001];
vector<pair<double, int>> v;
int solve(int sum, int i) {
  if (sum >= h)
    return 0;
  if (i == n + 1) {
    return 1e15;
  }
  int &res = dp[sum][i];
  if (res != -1)
    return res;
  res = 1e15;

  int ind = v[i - 1].second;
  int init = (h - sum) / (p[ind].first);
  for (int j = max(init - 10, (ll)0); j <= h; ++j) {
    res =
        min(res, (p[ind].second) * j + solve((p[ind].first) * j + sum, i + 1));
  }
  return res;
}
int32_t main() {
  IOS

          cin >>
      h >> n;

  for (int i = 1; i <= n; ++i)
    cin >> p[i].first >> p[i].second;

  for (int i = 1; i <= n; ++i) {
    double x = (double)p[i].first / (double)p[i].second;
    v.push_back({x, i});
  }
  sort(v.begin(), v.end());
  reverse(v.begin(), v.end());

  memset(dp, -1, sizeof(dp));
  cout << solve(0, 1);
}

Fixed submission:
// #include <ext/pb_ds/assoc_container.hpp>
//  #include <ext/pb_ds/tree_policy.hpp>
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>
using namespace std;
#define IOS                                                                    \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
#define trace(x) cerr << #x << ": " << x << " " << endl;

typedef int64_t ll;

#define endl '\n'
#define int ll
ll mod = 1e17;
ll mod1 = 1e9 + 5;

ll power(ll a, ll b) {
  if (b == 0)
    return 1;
  else if (b % 2 == 0)
    return power((((a % mod) * (a % mod)) % mod), b / 2) % mod;
  else
    return ((a % mod) * (power((((a % mod) * (a % mod)) % mod), b / 2) % mod)) %
           mod;
}

// using namespace __gnu_pbds;
// #define ordered_set tree<pair<int,int>, null_type,less<pair<int,int>>,
// rb_tree_tag,tree_order_statistics_node_update>
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;
// erase,insert same as normal set
int h, n;
pair<int, int> p[1000 + 1];
int dp[20001][1001];
vector<pair<double, int>> v;
int solve(int sum, int i) {
  if (sum >= h)
    return 0;
  if (i == n + 1) {
    return 1e15;
  }
  int &res = dp[sum][i];
  if (res != -1)
    return res;
  res = 1e15;

  int ind = v[i - 1].second;
  int init = (h - sum) / (p[ind].first);
  for (int j = max(init - 10, (ll)0); j <= (h - sum) / (p[ind].first) + 10;
       ++j) {
    res =
        min(res, (p[ind].second) * j + solve((p[ind].first) * j + sum, i + 1));
  }
  return res;
}
int32_t main() {
  IOS

          cin >>
      h >> n;

  for (int i = 1; i <= n; ++i)
    cin >> p[i].first >> p[i].second;

  for (int i = 1; i <= n; ++i) {
    double x = (double)p[i].first / (double)p[i].second;
    v.push_back({x, i});
  }
  sort(v.begin(), v.end());
  reverse(v.begin(), v.end());

  memset(dp, -1, sizeof(dp));
  cout << solve(0, 1);
}