Problem p02692 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <bits/stdc++.h>
using namespace std;
#define SELECTER(_1, _2, _3, SELECT, ...) SELECT
#define REP1(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define REP2(i, a, b) for (int(i) = (a); (i) < (b); (i)++)
#define REP(...) SELECTER(__VA_ARGS__, REP2, REP1, )(__VA_ARGS__)
#define MOD 1'000'000'007

template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "{";
  for (size_t i = 0; i < v.size(); i++)
    os << v[i] << (i + 1 == v.size() ? "" : ", ");
  os << "}";
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << "{" << p.first << ", " << p.second << "}";
}

const int MX = 5;

string naive(int N, int A, int B, int C, vector<int> &s) {
  string ans;
  for (int i = 0; i < N; i++) {
    if (s[i] == 0) {
      if (A > B) {
        A--;
        B++;
        ans += "B";
      } else {
        A++;
        B--;
        ans += "A";
      }
    }
    if (s[i] == 1) {
      if (B > C) {
        B--;
        C++;
        ans += "C";
      } else {
        B++;
        C--;
        ans += "B";
      }
    }
    if (s[i] == 2) {
      if (A > C) {
        A--;
        C++;
        ans += "C";
      } else {
        A++;
        C--;
        ans += "A";
      }
    }
    if (min(A, min(B, C)) < 0)
      return "";
  }
  return ans;
}

string rec(int N, int a, int b, int c,
           tuple<int, int, int> dp[100011][MX][MX][MX]) {
  string ret;
  for (int i = N; i > 0; i--) {
    int aa, bb, cc;
    tie(aa, bb, cc) = dp[i][a][b][c];
    if (a > aa)
      ret += "A";
    if (b > bb)
      ret += "B";
    if (c > cc)
      ret += "C";
    a = aa;
    b = bb;
    c = cc;
  }
  reverse(ret.begin(), ret.end());
  return ret;
}

tuple<int, int, int> dp[100011][MX][MX][MX];
string solve(int N, int A, int B, int C, vector<int> &s) {
  REP(i, N + 1)
  REP(a, MX) REP(b, MX) REP(c, MX) dp[i][a][b][c] = make_tuple(-1, -1, -1);
  dp[0][A][B][C] = make_tuple(0, 0, 0);
  for (int i = 0; i < N; i++) {
    REP(a, MX) REP(b, MX) REP(c, MX) {
      if (dp[i][a][b][c] == make_tuple(-1, -1, -1))
        continue;
      if (s[i] == 0) {
        if (a + 1 < MX && b - 1 >= 0)
          dp[i + 1][a + 1][b - 1][c] = make_tuple(a, b, c);
        if (a - 1 >= 0 && b + 1 < MX)
          dp[i + 1][a - 1][b + 1][c] = make_tuple(a, b, c);
      }
      if (s[i] == 1) {
        if (b + 1 < MX && c - 1 >= 0)
          dp[i + 1][a][b + 1][c - 1] = make_tuple(a, b, c);
        if (b - 1 >= 0 && c + 1 < MX)
          dp[i + 1][a][b - 1][c + 1] = make_tuple(a, b, c);
      }
      if (s[i] == 2) {
        if (a + 1 < MX && c - 1 >= 0)
          dp[i + 1][a + 1][b][c - 1] = make_tuple(a, b, c);
        if (a - 1 >= 0 && c + 1 < MX)
          dp[i + 1][a - 1][b][c + 1] = make_tuple(a, b, c);
      }
    }
  }
  bool ok = false;
  string ans;
  REP(a, MX) REP(b, MX) REP(c, MX) {
    if (ok)
      break;
    if (dp[N][a][b][c] != make_tuple(-1, -1, -1)) {
      ans = rec(N, a, b, c, dp);
      ok = true;
    }
  }
  return ans;
}

void check(int A, int B, int C, string ans, vector<int> &s) {
  for (int i = 0; i < ans.size(); i++) {
    char c = ans[i];
    if (s[i] == 0) {
      if (c == 'A') {
        A++;
        B--;
      } else {
        A--;
        B++;
      }
    }
    if (s[i] == 1) {
      if (c == 'B') {
        B++;
        C--;
      } else {
        B--;
        C++;
      }
    }
    if (s[i] == 2) {
      if (c == 'C') {
        C++;
        A--;
      } else {
        C--;
        A++;
      }
    }
    assert(A >= 0 && B >= 0 && C >= 0);
  }
}

int main() {
  int N, A, B, C;
  cin >> N >> A >> B >> C;
  vector<int> s(N);
  REP(i, N) {
    string tmp;
    cin >> tmp;
    if (tmp == "AB")
      s[i] = 0;
    if (tmp == "BC")
      s[i] = 1;
    if (tmp == "AC")
      s[i] = 2;
  }
  int mx = max(A, max(B, C));
  string ans;
  if (mx >= MX) {
    ans = naive(N, A, B, C, s);
  } else {
    ans = solve(N, A, B, C, s);
  }
  if (ans == "")
    cout << "No" << endl;
  else {
    cout << "Yes" << endl;
    for (int i = 0; i < ans.size(); i++)
      cout << ans[i] << endl;
    // check(A, B, C, ans, s);
  }
  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define SELECTER(_1, _2, _3, SELECT, ...) SELECT
#define REP1(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define REP2(i, a, b) for (int(i) = (a); (i) < (b); (i)++)
#define REP(...) SELECTER(__VA_ARGS__, REP2, REP1, )(__VA_ARGS__)
#define MOD 1'000'000'007

template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "{";
  for (size_t i = 0; i < v.size(); i++)
    os << v[i] << (i + 1 == v.size() ? "" : ", ");
  os << "}";
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << "{" << p.first << ", " << p.second << "}";
}

string naive(int N, int A, int B, int C, vector<int> &s) {
  string ans;
  for (int i = 0; i < N; i++) {
    if (s[i] == 0) {
      if (A > B) {
        A--;
        B++;
        ans += "B";
      } else {
        A++;
        B--;
        ans += "A";
      }
    }
    if (s[i] == 1) {
      if (B > C) {
        B--;
        C++;
        ans += "C";
      } else {
        B++;
        C--;
        ans += "B";
      }
    }
    if (s[i] == 2) {
      if (A > C) {
        A--;
        C++;
        ans += "C";
      } else {
        A++;
        C--;
        ans += "A";
      }
    }
    if (min(A, min(B, C)) < 0)
      return "";
  }
  return ans;
}

string rec(int N, int a, int b, int c,
           tuple<int, int, int> dp[100011][10][10][10]) {
  string ret;
  for (int i = N; i > 0; i--) {
    int aa, bb, cc;
    tie(aa, bb, cc) = dp[i][a][b][c];
    if (a > aa)
      ret += "A";
    if (b > bb)
      ret += "B";
    if (c > cc)
      ret += "C";
    a = aa;
    b = bb;
    c = cc;
  }
  reverse(ret.begin(), ret.end());
  return ret;
}

tuple<int, int, int> dp[100011][10][10][10];
string solve(int N, int A, int B, int C, vector<int> &s) {
  REP(i, N + 1)
  REP(a, 10) REP(b, 10) REP(c, 10) dp[i][a][b][c] = make_tuple(-1, -1, -1);
  dp[0][A][B][C] = make_tuple(0, 0, 0);
  for (int i = 0; i < N; i++) {
    REP(a, 10) REP(b, 10) REP(c, 10) {
      if (dp[i][a][b][c] == make_tuple(-1, -1, -1))
        continue;
      if (s[i] == 0) {
        if (a + 1 < 10 && b - 1 >= 0)
          dp[i + 1][a + 1][b - 1][c] = make_tuple(a, b, c);
        if (a - 1 >= 0 && b + 1 < 10)
          dp[i + 1][a - 1][b + 1][c] = make_tuple(a, b, c);
      }
      if (s[i] == 1) {
        if (b + 1 < 10 && c - 1 >= 0)
          dp[i + 1][a][b + 1][c - 1] = make_tuple(a, b, c);
        if (b - 1 >= 0 && c + 1 < 10)
          dp[i + 1][a][b - 1][c + 1] = make_tuple(a, b, c);
      }
      if (s[i] == 2) {
        if (a + 1 < 10 && c - 1 >= 0)
          dp[i + 1][a + 1][b][c - 1] = make_tuple(a, b, c);
        if (a - 1 >= 0 && c + 1 < 10)
          dp[i + 1][a - 1][b][c + 1] = make_tuple(a, b, c);
      }
    }
  }
  bool ok = false;
  string ans;
  REP(a, 10) REP(b, 10) REP(c, 10) {
    if (ok)
      break;
    if (dp[N][a][b][c] != make_tuple(-1, -1, -1)) {
      ans = rec(N, a, b, c, dp);
      ok = true;
    }
  }
  return ans;
}

void check(int A, int B, int C, string ans, vector<int> &s) {
  for (int i = 0; i < ans.size(); i++) {
    char c = ans[i];
    if (s[i] == 0) {
      if (c == 'A') {
        A++;
        B--;
      } else {
        A--;
        B++;
      }
    }
    if (s[i] == 1) {
      if (c == 'B') {
        B++;
        C--;
      } else {
        B--;
        C++;
      }
    }
    if (s[i] == 2) {
      if (c == 'C') {
        C++;
        A--;
      } else {
        C--;
        A++;
      }
    }
    assert(A >= 0 && B >= 0 && C >= 0);
  }
}

int main() {
  int N, A, B, C;
  cin >> N >> A >> B >> C;
  vector<int> s(N);
  REP(i, N) {
    string tmp;
    cin >> tmp;
    if (tmp == "AB")
      s[i] = 0;
    if (tmp == "BC")
      s[i] = 1;
    if (tmp == "AC")
      s[i] = 2;
  }
  int mx = max(A, max(B, C));
  string ans;
  if (mx >= 9) {
    ans = naive(N, A, B, C, s);
  } else {
    ans = solve(N, A, B, C, s);
  }
  if (ans == "")
    cout << "No" << endl;
  else {
    cout << "Yes" << endl;
    for (int i = 0; i < ans.size(); i++)
      cout << ans[i] << endl;
    // check(A, B, C, ans, s);
  }
  return 0;
}