Problem p03599 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <array>
#include <atomic>
#include <bitset>
#include <cassert>
#include <ccomplex>
#include <cctype>
#include <cerrno>
#include <cfenv>
#include <cfloat>
#include <chrono>
#include <cinttypes>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <codecvt>
#include <complex>
#include <condition_variable>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstdbool>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctgmath>
#include <ctime>
#include <cwchar>
#include <cwctype>
#include <deque>
#include <exception>
#include <forward_list>
#include <fstream>
#include <functional>
#include <future>
#include <initializer_list>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <mutex>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <system_error>
#include <thread>
#include <tuple>
#include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <valarray>
#include <vector>
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast")
using namespace std;
typedef int64_t ll;
typedef long double ld;
const ll INF = (1LL << 60);
const ld pi = acosl((ld)1);
const ll mod = 1000000007;
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};
const int ddx[8] = {1, 0, -1, -1, -1, 0, 1, 1};
const int ddy[8] = {1, 1, 1, 0, -1, -1, -1, 0};

ld dsum(ll n) {
  auto s = to_string(n);
  ld ret = 0;
  rep(i, s.size()) ret += (s[i] - '0');
  return ret;
}

ld f(ld n) { return n / dsum(n); }

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};

bool solve() {
  ll A, B, C, D, E, F;
  cin >> A >> B >> C >> D >> E >> F;
  vector<vector<bool>> dp(3002, vector<bool>(3002, false));
  dp[0][0] = true;
  rep(i, 3000) {
    rep(j, 3000) {
      if (!dp[i][j])
        continue;
      // Aを加える
      if (A * 100 + i + j <= F)
        dp[i + A * 100][j] = true;

      // Bを加える
      if (B * 100 + i + j <= F)
        dp[i + B * 100][j] = true;

      // 砂糖を加える
      ll sugar = j + C;
      if (i + sugar <= F && E * i / 100 >= sugar)
        dp[i][sugar] = true;

      // Dを加える。
      sugar = j + D;
      if (i + sugar <= F && E * i / 100 >= sugar)
        dp[i][sugar] = true;
    }
  }
  ll water;
  ll s;
  ld ans = 0;
  rep(i, 3000) {
    rep(j, 3000) {
      if (!dp[i][j])
        continue;
      if (i == 0 && j == 0)
        continue;
      ld per = (ld)((ld)j / (ld)(i + j));
      // cout<<per<<endl;
      if (per > ans) {
        water = i + j;
        s = j;
        ans = per;
      }
    }
  }
  if (ans == 0)
    return true;
  cout << water << " " << s << endl;
  return false;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << fixed;
  cout << setprecision(30);
  if (solve())
    return 1;
}


Fixed submission:
#include <algorithm>
#include <array>
#include <atomic>
#include <bitset>
#include <cassert>
#include <ccomplex>
#include <cctype>
#include <cerrno>
#include <cfenv>
#include <cfloat>
#include <chrono>
#include <cinttypes>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <codecvt>
#include <complex>
#include <condition_variable>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstdbool>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctgmath>
#include <ctime>
#include <cwchar>
#include <cwctype>
#include <deque>
#include <exception>
#include <forward_list>
#include <fstream>
#include <functional>
#include <future>
#include <initializer_list>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <mutex>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <system_error>
#include <thread>
#include <tuple>
#include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <valarray>
#include <vector>
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast")
using namespace std;
typedef int64_t ll;
typedef long double ld;
const ll INF = (1LL << 60);
const ld pi = acosl((ld)1);
const ll mod = 1000000007;
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};
const int ddx[8] = {1, 0, -1, -1, -1, 0, 1, 1};
const int ddy[8] = {1, 1, 1, 0, -1, -1, -1, 0};

ld dsum(ll n) {
  auto s = to_string(n);
  ld ret = 0;
  rep(i, s.size()) ret += (s[i] - '0');
  return ret;
}

ld f(ld n) { return n / dsum(n); }

template <typename Monoid> struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;

  int sz;
  vector<Monoid> seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n)
      sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) { seg[k + sz] = x; }

  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1)
        L = f(L, seg[a++]);
      if (b & 1)
        R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const { return seg[k + sz]; }

  template <typename C>
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while (a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if (check(nxt))
        a = 2 * a + type;
      else
        M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }

  template <typename C> int find_first(int a, const C &check) {
    Monoid L = M1;
    if (a <= 0) {
      if (check(f(L, seg[1])))
        return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if (a & 1) {
        Monoid nxt = f(L, seg[a]);
        if (check(nxt))
          return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template <typename C> int find_last(int b, const C &check) {
    Monoid R = M1;
    if (b >= sz) {
      if (check(f(seg[1], R)))
        return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for (b += sz; a < b; a >>= 1, b >>= 1) {
      if (b & 1) {
        Monoid nxt = f(seg[--b], R);
        if (check(nxt))
          return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};

bool solve() {
  ll A, B, C, D, E, F;
  cin >> A >> B >> C >> D >> E >> F;
  vector<vector<bool>> dp(3002, vector<bool>(3002, false));
  dp[0][0] = true;
  rep(i, 3000) {
    rep(j, 3000) {
      if (!dp[i][j])
        continue;
      // Aを加える
      if (A * 100 + i + j <= F)
        dp[i + A * 100][j] = true;

      // Bを加える
      if (B * 100 + i + j <= F)
        dp[i + B * 100][j] = true;

      // 砂糖を加える
      ll sugar = j + C;
      if (i + sugar <= F && E * i / 100 >= sugar)
        dp[i][sugar] = true;

      // Dを加える。
      sugar = j + D;
      if (i + sugar <= F && E * i / 100 >= sugar)
        dp[i][sugar] = true;
    }
  }
  ll water;
  ll s;
  ld ans = 0;
  rep(i, 3000) {
    rep(j, 3000) {
      if (!dp[i][j])
        continue;
      if (i == 0 && j == 0)
        continue;
      ld per = (ld)((ld)j / (ld)(i + j));
      // cout<<per<<endl;
      if (per > ans) {
        water = i + j;
        s = j;
        ans = per;
      }
    }
  }
  if (ans == 0) {
    cout << A * 100 << " " << 0 << endl;
  } else
    cout << water << " " << s << endl;
  return false;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << fixed;
  cout << setprecision(30);
  if (solve())
    return 1;
}