알고리즘
BOJ 1744: 수 묶기
minbear
2023. 6. 6. 22:06
#BOJ 1744: 수 묶기
1744번: 수 묶기
길이가 N인 수열이 주어졌을 때, 그 수열의 합을 구하려고 한다. 하지만, 그냥 그 수열의 합을 모두 더해서 구하는 것이 아니라, 수열의 두 수를 묶으려고 한다. 어떤 수를 묶으려고 할 때, 위치에
www.acmicpc.net
#풀이
그리디 연습하려고 푸는 문제인데 내가 그리디로 푸는 것인지 잘 모르겠다... 그냥 최선의 선택을 하려고 하는데 그냥 평소와 같이 생각하는 거 같다...
일단 이 문제는 괄호치는 거랑 비슷하다.
그래서 일단 조건이
1.양수*양수
2.음수*음수
3.양수*0
4.음수*0
있다. 이 중에서 괄호를 쳐하는 상황은 1,2,4 이어야 괄호를 쳐서 최대의 값을 만들 수 있다.
일단 정렬을 해서 뒤에서 부터 2개씩 숫자를 묶고 0을 만났을 때
다시 인덱스 처음으로 돌아가서 앞에서 2개씩 묶는다.
그러는 이유가 2번이 문제인데 음수 * 음수 는 양수가 되므로 가장 작은 수끼리 곱해야 가장 큰 수 가 나온다.
또한 인덱스 를 뒤에서 부터 오는 경우는 1*1을 괄호로 묶지 않도로 해야한다. 그냥 인덱스값이 1보다 클 때 괄호로 묶으면!
그리고 음수는 음수* 0 을 생각해야하는데 이것도 쉽다.
항상 문제를 풀 때 조건을 먼저 생각하게 되는데 뭔가 평소랑 다를 거 없이 풀어서 내가 그리디로 풀 고 있는지 뭔가 의심이 간다!! 나도 잘하고 싶다~~ minbear 우승!!
#코드
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int arr[52];
int ans;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> arr[i];
}
arr[0] = 1; //arr[1]*arr[0] == arr[1] 를 유지
arr[n + 1] = 1; //arr[n]*arr[n+1] == arr[n] 를 유지
sort(arr + 1, arr + n+1);
int j = 0; // 0부터 음수 까지
for (int i = n; i >= 1; i--) { // 양수 뒤에서 부터 2개씩 묶음
if (arr[i] > 1 && arr[i - 1] > 1)
{
ans = ans + arr[i] * arr[i - 1];
i--;
}
else if (arr[i] <= 0)
{
j = i;
break;
}
else
ans = ans + arr[i];
}
// 음수
for (int i = 1; i <= j; i++) { // 앞에서 부터 2개씩 묶음
if (arr[i] < 0 && arr[i + 1] < 0)
{
ans = ans + arr[i] * arr[i + 1];
i++;
}
else if (arr[i] < 0 && arr[i + 1] == 0)
{
i++;
}
else
ans = ans + arr[i];
}
cout << ans << '\n';
return 0;
}