Problem p03008 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <string>
#include <tuple>
#include <vector>
using namespace std;
#define MOD (long long int)(1e9 + 7)
#define ll long long int
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, n) for (int i = 1; i <= (int)(n); i++)
#define REP(i, n) for (int i = n - 1; i >= 0; i--)
#define REPS(i, n) for (int i = n; i > 0; i--)
#define INF (int)(1123456789)
#define LINF (long long int)(112345678901234567)
#define chmax(a, b) a = (((a) < (b)) ? (b) : (a))
#define chmin(a, b) a = (((a) > (b)) ? (b) : (a))
#define all(v) v.begin(), v.end()

int main(void) {
  ll n;
  cin >> n;
  ll g1, s1, b1, g2, s2, b2;
  cin >> g1 >> s1 >> b1;
  cin >> g2 >> s2 >> b2;
  ll don = n;
  ll max_value = 0;
  rep(gi, don / g1 + 1) {
    rep(si, don / s1 + 1) {
      ll sum = g1 * gi + s1 * si;
      ll remain = don - sum;
      if (remain < 0)
        break;
      chmax(max_value, (g2 - g1) * gi + (s2 - s1) * si +
                           max((ll)0, (b2 - b1) * (remain / b1)));
    }
  }
  don += max_value;

  max_value = 0;
  rep(gi, don / g2 + 1) {
    rep(si, don / s2 + 1) {
      ll sum = g2 * gi + s2 * si;
      ll remain = don - sum;
      if (remain < 0)
        break;
      chmax(max_value, (g1 - g2) * gi + (s1 - s2) * si +
                           max((ll)0, (b1 - b2) * (remain / b2)));
    }
  }
  don += max_value;

  cout << don << endl;

  /*ll n;
  cin>>n;
  ll in1,in2,in3;
  cin>>in1>>in2>>in3;
  ll in4,in5,in6;
  cin>>in4>>in5>>in6;
  ll sa1,sa2,sa3;
  sa1 = in4-in1;
  sa2 = in5-in2;
  sa3 = in6-in3;
  ll g1,s1,b1,g2,s2,b2;
  if(sa1 >= sa2 && sa1 >= sa3){
          g1 = in1;
          g2 = in4;
          if(sa2 >= sa3){
                  s1 = in2;
                  s2 = in5;
                  b1 = in3;
                  b2 = in6;
          }else{
                  s1 = in3;
                  s2 = in6;
                  b1 = in2;
                  b2 = in5;
          }
  }else if(sa2 >= sa3){
          g1 = in2;
          g2 = in5;
          if(sa1 >= sa3){
                  s1 = in1;
                  s2 = in4;
                  b1 = in3;
                  b2 = in6;
          }else{
                  s1 = in3;
                  s2 = in6;
                  b1 = in1;
                  b2 = in4;
          }
  }else{
          g1 = in3;
          g2 = in6;
          if(sa1 >= sa2){
                  s1 = in1;
                  s2 = in4;
                  b1 = in2;
                  b2 = in5;
          }else{
                  s1 = in2;
                  s2 = in5;
                  b1 = in1;
                  b2 = in4;
          }
  }

  //利益はg>s>b

  //第一世代のどんぐり数
  ll don = n;
  if(g2 - g1 <= 0){
  }else if(s2 - s1 <= 0){
          don = don + (g2 - g1) * (don / g1);
  }else if(b2 - b1 <= 0){
          ll max = 0;
          rep(gi, don/g1){
                  rep(si, don/s1){
                          //gi*g1個とsi*s1個それぞれ買う

                          if(gi*g1 + si*s1 > don) break;
                          chmax(max, (g2-g1) * gi + (s2-s1) * si);
                  }
          }
          don = don + max;
  }else{
          //得られる利益、残りの個数
          vector<pair<ll, ll>> GS;
          rep(gi, don/g1){
                  rep(si, don/s1){

                          if(gi*g1 + si*s1 > don) break;
                          GS.push_back(pair<ll,ll>{(g2-g1) * gi + (s2-s1) * si,
  don - gi*g1 + si*s1});
                  }
          }
          sort(all(GS));
          reverse(all(GS));

          //利益が高く、残り個数が大きいものを高評価としてsort
          ll max = 0;
          rep(i, GS.size()){
                  ll remain = GS[i].second;
                  chmax(max, GS[i].first + (b2-b1) * (remain / b1));
          }
          don = don + max;
  }

  cout<<don<<endl;
  //第二世代を計算
  ll tmp;
  tmp = g1;g1 = g2;g2 = tmp;
  tmp = s1;s1 = s2;s2 = tmp;
  tmp = b1;b1 = b2;b2 = tmp;

  tmp = g1;g1 = b1;b1 = tmp;
  tmp = g2;g2 = b2;b2 = tmp;

  if(g2 - g1 <= 0){
  }else if(s2 - s1 <= 0){
          don = don + (g2 - g1) * (don / g1);
  }else if(b2 - b1 <= 0){
          ll max = 0;
          rep(gi, don/g1){
                  rep(si, don/s1){
                          //gi*g1個とsi*s1個それぞれ買う

                          if(gi*g1 + si*s1 > don) break;
                          chmax(max, (g2-g1) * gi + (s2-s1) * si);
                  }
          }
          don = don + max;
  }else{
          //得られる利益、残りの個数
          vector<pair<ll, ll>> GS;
          rep(gi, don/g1){
                  rep(si, don/s1){

                          if(gi*g1 + si*s1 > don) break;
                          GS.push_back(pair<ll,ll>{(g2-g1) * gi + (s2-s1) * si,
  don - gi*g1 + si*s1});
                  }
          }
          sort(all(GS));
          reverse(all(GS));

          //利益が高く、残り個数が大きいものを高評価としてsort
          ll max = 0;
          rep(i, GS.size()){
                  ll remain = GS[i].second;
                  chmax(max, GS[i].first + (b2-b1) * (remain / b1));
          }
          don = don + max;
  }

  cout<<don<<endl;

  return 0;*/
}


Fixed submission:
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <string>
#include <tuple>
#include <vector>
using namespace std;
#define MOD (long long int)(1e9 + 7)
#define ll long long int
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, n) for (int i = 1; i <= (int)(n); i++)
#define REP(i, n) for (int i = n - 1; i >= 0; i--)
#define REPS(i, n) for (int i = n; i > 0; i--)
#define INF (int)(1123456789)
#define LINF (long long int)(112345678901234567)
#define chmax(a, b) a = (((a) < (b)) ? (b) : (a))
#define chmin(a, b) a = (((a) > (b)) ? (b) : (a))
#define all(v) v.begin(), v.end()

int main(void) {
  ll n;
  cin >> n;
  ll g1, s1, b1, g2, s2, b2;
  cin >> g1 >> s1 >> b1;
  cin >> g2 >> s2 >> b2;
  ll don = n;
  ll max_value = 0;
  rep(gi, don / g1 + 1) {
    rep(si, don / s1 + 1) {
      ll sum = g1 * gi + s1 * si;
      ll remain = don - sum;
      if (remain < 0)
        break;
      chmax(max_value, (g2 - g1) * gi + (s2 - s1) * si +
                           max((ll)0, (b2 - b1) * (remain / b1)));
    }
  }
  don += max_value;

  if (max_value > 0) {
    ll x1, x2, y1, y2; // a2Toa1, b2Tob1
    if (g2 - g1 > 0) {
      x1 = s1;
      x2 = s2;
      y1 = b1;
      y2 = b2;
    } else if (s2 - s1 > 0) {
      x1 = g1;
      x2 = g2;
      y1 = b1;
      y2 = b2;
    } else {
      x1 = g1;
      x2 = g2;
      y1 = s1;
      y2 = s2;
    }

    ll max_value = 0;
    rep(xi, don / x2 + 1) {
      ll sum = x2 * xi;
      ll remain = don - sum;
      if (remain < 0)
        break;
      chmax(max_value, (x1 - x2) * xi + max((ll)0, (y1 - y2) * (remain / y2)));
    }
    don += max_value;
    cout << don << endl;
    return 0;
  }

  max_value = 0;
  rep(gi, don / g2 + 1) {
    rep(si, don / s2 + 1) {
      ll sum = g2 * gi + s2 * si;
      ll remain = don - sum;
      if (remain < 0)
        break;
      chmax(max_value, (g1 - g2) * gi + (s1 - s2) * si +
                           max((ll)0, (b1 - b2) * (remain / b2)));
    }
  }
  don += max_value;

  cout << don << endl;

  /*ll n;
  cin>>n;
  ll in1,in2,in3;
  cin>>in1>>in2>>in3;
  ll in4,in5,in6;
  cin>>in4>>in5>>in6;
  ll sa1,sa2,sa3;
  sa1 = in4-in1;
  sa2 = in5-in2;
  sa3 = in6-in3;
  ll g1,s1,b1,g2,s2,b2;
  if(sa1 >= sa2 && sa1 >= sa3){
          g1 = in1;
          g2 = in4;
          if(sa2 >= sa3){
                  s1 = in2;
                  s2 = in5;
                  b1 = in3;
                  b2 = in6;
          }else{
                  s1 = in3;
                  s2 = in6;
                  b1 = in2;
                  b2 = in5;
          }
  }else if(sa2 >= sa3){
          g1 = in2;
          g2 = in5;
          if(sa1 >= sa3){
                  s1 = in1;
                  s2 = in4;
                  b1 = in3;
                  b2 = in6;
          }else{
                  s1 = in3;
                  s2 = in6;
                  b1 = in1;
                  b2 = in4;
          }
  }else{
          g1 = in3;
          g2 = in6;
          if(sa1 >= sa2){
                  s1 = in1;
                  s2 = in4;
                  b1 = in2;
                  b2 = in5;
          }else{
                  s1 = in2;
                  s2 = in5;
                  b1 = in1;
                  b2 = in4;
          }
  }

  //利益はg>s>b

  //第一世代のどんぐり数
  ll don = n;
  if(g2 - g1 <= 0){
  }else if(s2 - s1 <= 0){
          don = don + (g2 - g1) * (don / g1);
  }else if(b2 - b1 <= 0){
          ll max = 0;
          rep(gi, don/g1){
                  rep(si, don/s1){
                          //gi*g1個とsi*s1個それぞれ買う

                          if(gi*g1 + si*s1 > don) break;
                          chmax(max, (g2-g1) * gi + (s2-s1) * si);
                  }
          }
          don = don + max;
  }else{
          //得られる利益、残りの個数
          vector<pair<ll, ll>> GS;
          rep(gi, don/g1){
                  rep(si, don/s1){

                          if(gi*g1 + si*s1 > don) break;
                          GS.push_back(pair<ll,ll>{(g2-g1) * gi + (s2-s1) * si,
  don - gi*g1 + si*s1});
                  }
          }
          sort(all(GS));
          reverse(all(GS));

          //利益が高く、残り個数が大きいものを高評価としてsort
          ll max = 0;
          rep(i, GS.size()){
                  ll remain = GS[i].second;
                  chmax(max, GS[i].first + (b2-b1) * (remain / b1));
          }
          don = don + max;
  }

  cout<<don<<endl;
  //第二世代を計算
  ll tmp;
  tmp = g1;g1 = g2;g2 = tmp;
  tmp = s1;s1 = s2;s2 = tmp;
  tmp = b1;b1 = b2;b2 = tmp;

  tmp = g1;g1 = b1;b1 = tmp;
  tmp = g2;g2 = b2;b2 = tmp;

  if(g2 - g1 <= 0){
  }else if(s2 - s1 <= 0){
          don = don + (g2 - g1) * (don / g1);
  }else if(b2 - b1 <= 0){
          ll max = 0;
          rep(gi, don/g1){
                  rep(si, don/s1){
                          //gi*g1個とsi*s1個それぞれ買う

                          if(gi*g1 + si*s1 > don) break;
                          chmax(max, (g2-g1) * gi + (s2-s1) * si);
                  }
          }
          don = don + max;
  }else{
          //得られる利益、残りの個数
          vector<pair<ll, ll>> GS;
          rep(gi, don/g1){
                  rep(si, don/s1){

                          if(gi*g1 + si*s1 > don) break;
                          GS.push_back(pair<ll,ll>{(g2-g1) * gi + (s2-s1) * si,
  don - gi*g1 + si*s1});
                  }
          }
          sort(all(GS));
          reverse(all(GS));

          //利益が高く、残り個数が大きいものを高評価としてsort
          ll max = 0;
          rep(i, GS.size()){
                  ll remain = GS[i].second;
                  chmax(max, GS[i].first + (b2-b1) * (remain / b1));
          }
          don = don + max;
  }

  cout<<don<<endl;

  return 0;*/
}