코딩 테스트/백준

[Python] 백준 14247 나무 자르기

위시리 2025. 3. 17. 21:14

 

문제 분석

  • n개의 나무
  • 하루에 한 나무씩 / n일 산에 오르며 나무를 잘라갈 것이다.
  • 밤이 되면 나무는 빠른 속도로 자라는데 자라는 길이는 나무마다 다름
  • 어느 나무를 잘라가느냐에 따라 총 구할 수 있는 나무의 양이 다름

  • 나무의 처음 길이와 하루에 자라는 양이 주어졌을 때, 영선이가 얻을 수 있는 최대 나무 양을 구하라
  • 자른 이후에도 나무는 0부터 다시 자라기 때ㅜㅁㄴ에 같은 나무를 여러 번 자를 수 있다.

  • 나무 : 1번부터 n번
  • 다음 줄에는 첫날 올라갔을 때 나무의 길이
  • 나무들이 자라는 길이

  • 나무를 잘라서 구할 수 있는 최대 양

 

풀이

  • 나무의 수 : n → n일 동안 산을 오르면서 나무를 잘라나갈 것
  • 하루에 성장할 수 있는 길이가 가장 긴 나무를 제일 마지막에 자르는 것이 잘라가는 나무 길이의 최대 값을 얻을 수 있는 방법
  • 하루에 성장할 수 있는 길이가 가장 긴 나무를 제일 마지막 날에 자른다면, 그 전날에는 어떤 나무를 잘라야 하는가?

  • 하루에 성장할 수 있는 나무의 길이들을 정렬해서 세웠을 때, 끝에서 두번째 나무를 잘라야 한다.
  • n-1 일까지 가장 많이 나무를 성장시킨 후 자르려면 n-1번째로 성장 길이가 큰 나무를 잘라야 한다.
  • 이렇게 매 순간 최적의 해를 선택하는 것이 최종적으로 최적의 정답을 만들어내는 그리디 알고리즘이다.
  • 제일 마지막날 자를 나무 : 가장 많이 성장한 나무
  • 최적의 해를 선택하는 과정을 역순으로 매일 진행 → 최적의 해

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

  • 하루에 성장할 수 있는 길이가 짧은 나무를 기준으로 잘라야 한다.
  • 하루에 성장할 수 있는 나무의 길이를 기준으로 정렬

  • 이후 1일부터 n일까지 나무를 순차적으로 자른다.
  • 이때 획득할 수 있는 나무의 양은 초기 나무 길이 + i일까지의 성방분 (i * 하루 성장 길이)

 

정답 코드

import sys
input = sys.stdin.readline

n = int(input())
height = list(map(int, input().split()))
growth = list(map(int, input().split()))

# 자라는 길이에 대해 정렬
trees = []
for i in range(n) :
    trees.append([growth[i], height[i]])

trees.sort() # 자라는 길이에 대해 정렬

ans = 0
# n-1 일부터 첫날까지
for i in range(n) :
    ans += trees[i][1] + trees[i][0] * i
print(ans)