[BOJ 14247] 나무 자르기

Lil_Young·2025년 8월 3일

알고리즘 문제

목록 보기
15/23
post-thumbnail

문제


영선이는 나무꾼으로 나무를 구하러 오전에 산에 오른다. 산에는
nn개의 나무가 있는데, 영선이는 하루에 한 나무씩 nn일 산에 오르며 나무를 잘라갈 것이다. 하지만 이 산은 영험한 기운이 있어 나무들이 밤만 되면 매우 빠른 속도로 자라는데, 그 자라는 길이는 나무마다 다르다.

따라서, 어느 나무를 먼저 잘라가느냐에 따라서 총 구할 수 있는 나무의 양이 다른데,

나무의 처음 길이와 하루에 자라는 양이 주어졌을 때, 영선이가 얻을 수 있는 최대 나무양을 구하시오.

참고로, 자른 이후에도 나무는
00부터 다시 자라기 때문에 같은 나무를 여러 번 자를 수는 있다.

[입력]
첫째 줄에는 나무의 개수 nn개가 있다. 나무는 11번부터 nn번까지 있다.

다음 줄에는 첫날 올라갔을 때 나무의 길이들 HiH_inn개가 순서대로 주어진다.

그 다음 줄에는 나무들이 자라는 길이 AiA_inn개가 순서대로 주어진다.

[출력]
영선이가 나무를 잘라서 구할 수 있는 최대 양을 출력하시오.

[제한]
1n1000001≤n≤100\,000

1Hi1000001≤H_i≤100\,000

1Ai100001≤A_i≤10\,000

[풀이 코드]


import java.io.*;
import java.util.*;

public class 나무자르기 {
	static class tree{
		int value, speed;
		tree(int value, int speed){
			this.value=value;
			this.speed=speed;
		}
	}
	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int N = Integer.parseInt(br.readLine());
		int[] arr = new int[N];
		StringTokenizer st = new StringTokenizer(br.readLine());
		for (int i = 0; i < N; i++) {
			arr[i] = Integer.parseInt(st.nextToken());
		}
		int[] arr2 = new int[N];
		st = new StringTokenizer(br.readLine());
		for (int i = 0; i < N; i++) {
			arr2[i] = Integer.parseInt(st.nextToken());
		}
		tree[] trees = new tree[N];
		for (int i = 0; i < N; i++) {
			trees[i] = new tree(arr[i], arr2[i]);
		}
		Arrays.sort(trees, (o1, o2) -> o1.speed - o2.speed);
		
		long result = 0;
		for (int i = 0; i < N; i++) {
			result+=trees[i].value+(trees[i].speed*i);
		}
		System.out.println(result);
	}
}

이 문제를 접했을 때 n이 1부터 10만까지여서 바이너리 서치로 풀어야 된다고 생각을 했다.
그런데 문제를 보니 나무를 자루는 순서만 잘 정하면 답이 바로 나오겠단 생각이 들었다.

그래서 i번째 날에 얻은 나무 길이는 H+A*i 로 했고 성장 속도가 큰 나무를 뒤에 자르면 자라는 시간이 길어져서 이득이여서 성장 속도가 작은 나무부터 잘라야 하기 때문에 성장 속도를 기준으로 오름차순 정렬을 했다.

0개의 댓글