Notice
Recent Posts
Recent Comments
Link
승코딩당당당
[C++] 백준 1744: 수 묶기 본문
문제
[C++] 백준 1744: 수 묶기 GOLD 4
https://www.acmicpc.net/problem/1744

접근 방법
이 문제는 주어진 정수들을 적절히 묶어서(곱하거나 더해서) 전체 합의 최댓값을 만드는 문제다.
핵심 아이디어는 수의 성질에 따라 전략을 나누는 그리디 접근이다.
수들을 다음 네 종류로 분리한다.
- 1보다 큰 양수
→ 두 개씩 묶어서 곱하는 것이 이득 - 음수
→ 두 개씩 묶어서 곱하면 양수가 되어 이득 - 1
→ 어떤 수와 곱해도 이득이 없으므로 그냥 더함 - 0
→ 남는 음수 하나를 제거(상쇄)하는 용도로 사용
이를 위해
- 양수(>1)는 내림차순 우선순위 큐
- 음수는 오름차순 우선순위 큐
로 관리한다.
구현 시 주의할 점
- 1은 절대 곱하지 않는다.
1 × x ≤ 1 + x 이므로 항상 더하는 게 이득이다. - 음수가 하나 남았을 때
- 0이 있으면 0과 묶어 없애고
- 0이 없으면 그대로 더해야 한다.
- 모든 묶기 작업이 끝난 뒤,
남은 값들과 1의 개수를 모두 합산하면 최댓값이 된다.
코드
#include <iostream>
#include <queue>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n = 0;
cin >> n;
priority_queue<int> posi; // 1보다 큰 양수
priority_queue<int, vector<int>, greater<int>> nega; // 음수
int one = 0, zero = 0; // 1, 0의 개수
int num = 0;
for (int i = 0; i < n; i++)
{
cin >> num;
if (num > 1)
posi.push(num);
else if (num < 0)
nega.push(num);
else if (num == 1)
one++;
else
zero++;
}
int sum = 0;
// 양수 처리
while (posi.size() > 1)
{
int first = posi.top();
posi.pop();
int second = posi.top();
posi.pop();
sum += (first * second);
}
if (!posi.empty())
sum += posi.top();
// 음수 처리
while (nega.size() > 1)
{
int first = nega.top();
nega.pop();
int second = nega.top();
nega.pop();
sum += (first * second);
}
if ((!nega.empty()) && (zero == 0))
sum += nega.top();
sum += one;
cout << sum;
return 0;
}'PS > BOJ' 카테고리의 다른 글
| [C++] 백준 22864: 피로도 (0) | 2026.02.01 |
|---|---|
| [C++] 백준 1541: 잃어버린 괄호 (2) | 2026.02.01 |
| [C++] 백준 1715: 카드 정렬하기 (0) | 2026.01.31 |
| [C++] 백준 11047: 동전 0 (0) | 2026.01.31 |
| [C++] 백준 2512: 예산 (1) | 2026.01.31 |