[백준] 1744번: 수 묶기

2018. 6. 3. 00:29알고리즘

 

1744번: 수 묶기

길이가 N인 수열이 주어졌을 때, 그 수열의 합을 구하려고 한다. 하지만, 그냥 그 수열의 합을 모두 더해서 구하는 것이 아니라, 수열의 두 수를 묶으려고 한다. 어떤 수를 묶으려고 할 때, 위치에 상관없이 묶을 수 있다. 하지만, 같은 위치에 있는 수(자기 자신)를 묶는 것은 불가능하다. 그리고 어떤 수를 묶게 되면, 수열의 합을 구할 때 묶은 수는 서로 곱한 후에 더한다. 예를 들면, 어떤 수열이 {0, 1, 2, 4, 3, 5}일 때, 그냥 이 수열

www.acmicpc.net

 

 

이 문제는 그리디 문제는 맞지만 다른 그리디 문제보다는 신경 써주어야 할 조건들이 많습니다.

 

* 수들을 두 개씩 묶거나 묶지 않을 수 있다. (곱하지 않을 수 있다.)

* 적절히 묶은 수열의 합을 구했을 때 그 값의 최댓값을 구하는 것이 문제다.

 

여기서 절댓값이 큰 순서대로 곱해줄 경우, 합의 최댓값이 가장 큼을 알 수 있습니다.

-5, -4, 5, 6이 있다면, -5와 -4, 5와 6을 곱해주는 경우가 가장 큽니다.

또, 부호의 변경을 신경 써 주어야 합니다.

 

 

여기서 주의 깊게 보아야 할 포인트는 세 가지가 있습니다.

 

1. 각 수의 부호

2. 0 (어떤 수든 0을 곱해주면 0이 된다. 음수의 갯수가 짝수가 아니라면, 곱해서 양수로 변환 되지 못한 음수가 하나 남는데, 이 음수에 0을 곱해주면 0이 된다는 점을 이용합니다.)

3. 1 (1은 어떤 수를 곱해도 자기 자신을 반환하기 때문에, 1은 그냥 더해주는 것이 합의 최댓값을 구하는 데 도움이 됩니다.)

 

그리디로 문제를 풀어야 하므로 std::sort 를 이용하여 정렬을 한 후, 정렬된 수열을 이용하여 합의 최댓값을 구합니다.

 

 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int N;
vector<int> negative;
vector<int> positive;
int zero = 0;
int one = 0;

void input() {
  cin >> N;

  for (int i = 0; i < N; i++) {
    int x;
    cin >> x;
    
    if (x < 0) {
      negative.push_back(x);
    }
    else if (x == 0) {
      zero++;
    }
    else if (x == 1) {
      one++;
    }
    else {
      positive.push_back(x);
    }
  }
}

void sortSequence() {
  sort(negative.begin(), negative.end());
  sort(positive.begin(), positive.end());
}

long long calculateNegative() {
  long long ans = 0;
  int size = negative.size();

  for (int i = 0; i < size; i += 2) {
    if (i + 1 == size) {
      if (zero == 0) {
        ans += negative[i];
        break;
      }
    }
    ans += negative[i] * negative[i + 1];
  }
  return ans;
}

long long calculatePositive() {
  long long ans = 0;
  int size = positive.size();

  for (int i = size - 1; i >= 0; i -= 2) {
    if (i - 1 < 0) {
      ans += positive[i];
      break;
    }
    ans += positive[i] * positive[i - 1];
  }
  return ans;
}

long long calculateSum() {
  long long ans = calculateNegative() + calculatePositive() + one;

  return ans;
}

void printAnswer(long long ans) {
  cout << ans << '\n';
}

int main() {
  ios::sync_with_stdio(false);

  input();
  sortSequence();
  long long ans = calculateSum();
  printAnswer(ans);

  return 0;
}

 

'알고리즘' 카테고리의 다른 글

[백준] 1783번: 병든 나이트  (0) 2018.06.06
[백준] 10610번: 30  (0) 2018.06.03
[백준] 1541번: 잃어버린 괄호  (0) 2018.06.02
[백준] 11399번: ATM  (0) 2018.06.02
[백준] 1931번: 회의실 배정  (0) 2018.06.02