Stunning Garbanzo
open main menu
Part of series: PS

16637 BOJ

/ 4 min read

문제

접근

브루트포스 알고리즘을 이용해 해결하였다.

완전 탐색을 통해 모든 경우의 수를 비교해 정답을 도출하였다. 주의해야할 점은, 특정 부분에서의 최대값이 전체에서의 최대값을 이루는데 사용되지 않을 수 있다는 점이다.

뒤에서부터 탐색해 가장 큰 값을 가지는 경우를 찾았는데, 처음에는 뒤의 원소를 소모하고 재귀적으로 앞의 원소를 소모하게 풀이했다. 이러한 경우, 음수 곱하기 음수 같은 케이스를 고려할 수 없게 된다. 늘 부분적으로 최대값을 가지로 조합만 이끌어내기 때문이다. 따라서 최대값을 구하는 함수 외에도 최소값을 구하는 함수도 추가로 만들어 모든 경우의 수를 고려하게 하였다.

코드

#include <bits/stdc++.h>
#include <climits>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef const ll cll;
typedef queue<ll> qll;
typedef queue<pll> qpll;
typedef priority_queue<ll> pqll;
typedef priority_queue<pll> pqpll;
typedef vector<ll> vll;
typedef vector<pll> vpll;
typedef vector<vll> vvll;
typedef vector<vpll> vvpll;
#define FOR1(a, A) for (ll a = 0; a < A; ++a)
#define FOR2(a, b, A, B)                                                       \
  for (ll a = 0; a < A; ++a)                                                   \
    for (ll b = 0; b < B; ++b)

cll N = 19;
ll n;
string form;
ll minFind(string &form, ll idx);
ll maxFind(string &form, ll idx);

ll minFind(string &form, ll idx) {
  ll num = form[idx] - '0', nextNum, _result, result;
  if (idx == 0) {
    return num;
  }

  switch (form[idx - 1]) {
  case '+':
    result = num + minFind(form, idx - 2);
    break;
  case '-':
    result = minFind(form, idx - 2) - num;
    break;
  case '*':
    result = num * maxFind(form, idx - 2);
    result = min(result, num * minFind(form, idx - 2));
    break;
  }

  if (idx < 4) {
    goto END;
  }

  nextNum = form[idx - 2] - '0';
  switch (form[idx - 1]) {
  case '+':
    _result = num + nextNum;
    break;
  case '-':
    _result = nextNum - num;
    break;
  case '*':
    _result = num * nextNum;
    break;
  }

  switch (form[idx - 3]) {
  case '+':
    result = min(result, _result + minFind(form, idx - 4));
    break;
  case '-':
    result = min(result, minFind(form, idx - 4) - _result);
    break;
  case '*':
    result = min(result, _result * minFind(form, idx - 4));
    result = min(result, _result * maxFind(form, idx - 4));
    break;
  }

END:
  return result;
}

ll maxFind(string &form, ll idx) {
  ll num = form[idx] - '0', nextNum, _result, result;
  if (idx == 0) {
    return num;
  }

  switch (form[idx - 1]) {
  case '+':
    result = num + maxFind(form, idx - 2);
    break;
  case '-':
    result = maxFind(form, idx - 2) - num;
    break;
  case '*':
    result = num * maxFind(form, idx - 2);
    result = max(result, num * minFind(form, idx - 2));
    break;
  }

  if (idx < 4) {
    goto END;
  }

  nextNum = form[idx - 2] - '0';
  switch (form[idx - 1]) {
  case '+':
    _result = num + nextNum;
    break;
  case '-':
    _result = nextNum - num;
    break;
  case '*':
    _result = num * nextNum;
    break;
  }

  switch (form[idx - 3]) {
  case '+':
    result = max(result, _result + maxFind(form, idx - 4));
    break;
  case '-':
    result = max(result, maxFind(form, idx - 4) - _result);
    break;
  case '*':
    result = max(result, _result * minFind(form, idx - 4));
    result = max(result, _result * maxFind(form, idx - 4));
    break;
  }

END:
  return result;
}

int main(void) {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  cin >> n;
  cin >> form;

  ll result = maxFind(form, form.size() - 1);
  cout << result << "\n";

  return 0;
}