[BOJ] 1744 수 묶기

그리디


해당 문제를 그리디로 접근한 정당성은 다음과 같다.

  • 두 수씩 곱하고 이를 더해서 최대를 구해야 한다, 그런데 두 수를 주어진대로가 아닌 리스트에서 아무거나 두 개를 뽑아서 더하면 된다. 한 번 곱한 수는 다시 사용할 수 없다.
  • 따라서 정렬을 하면 되겠다는 생각 → 음수도 곱해도 양수가 되니 음수는 음수끼리 곱해야 겠다는 생각 → 두 개의 리스트로 만들어서, 절대값이 큰 순서로 내림차순 정렬을 하고 두 개씩 인덱스를 넘기며 탐색하면 최적의 해가 나올 것이라는 판단

0은 음수와 곱하면 -부호가 사라지는 역할을 하기 때문에 음수 리스트에 추가

처음에는 1을 양수 리스트에 추가 했다가 1, 2 인 경우 1*2 를 해버려서 결과가 2가 나와서 틀렸다. 최대 값은 1은 그냥 더하는 1 + 2 인데 이 점을 디버깅 하는데 꽤 오랜 시간이 걸렸다.

따라서 1은 리스트에 넣지 않고 그냥 바로 결과에 더해주었다.

import sys

def solution(seq, n):
    answer = 0
    positive_seq = list()
    negative_seq = list()
    for num in seq:
        if num <= 0:  # 0은 음수랑 곱하면 0이 되므로 여기에 포함
            negative_seq.append(num)
        elif num > 1:  # 1은 그냥 더하는게 곱하는거보다 크다
            positive_seq.append(num)
        else:           # 1은 그냥 더한다.
            answer += 1

    positive_seq.sort(reverse=True)
    negative_seq.sort()

    p_seq_len = len(positive_seq)
    n_seq_len = len(negative_seq)

    for i in range(1, p_seq_len, 2):
        answer += positive_seq[i] * positive_seq[i-1]
    if p_seq_len % 2 == 1:  # 배열 길이가 홀수면 마지막 원소 더함
        answer += positive_seq[-1]

    for i in range(1, n_seq_len, 2):
        answer += negative_seq[i] * negative_seq[i-1]
    if n_seq_len % 2 == 1:  # 배열 길이가 홀수면 마지막 원소 더함
        answer += negative_seq[-1]

    return answer

if __name__ == "__main__":
    N = int(sys.stdin.readline().rstrip())
    _seq = list()
    for _ in range(N):
        _seq.append(int(sys.stdin.readline().rstrip()))
    print(solution(_seq, N))

태그:

카테고리:

업데이트: