문제
14247번: 나무 자르기
영선이는 나무꾼으로 나무를 구하러 오전에 산에 오른다. 산에는 n개의 나무가 있는데, 영선이는 하루에 한 나무씩 n일 산에 오르며 나무를 잘라갈 것이다. 하지만 이 산은 영험한 기운이 있어
www.acmicpc.net
문제 풀이
처음엔 그날 그날의 나무 중에서 가장 큰 걸 자르도록 구현했는데, 이렇게 하면 주어진 테스트 케이스도 맞추지 못한다.
나무1 | 나무2 | 나무3 | 나무4 | 나무5 | |
1일째 | 1 | 3 | 2 | 4 | 6 |
2일째 | 3 | 10 | 5 | 8 | 1 |
3일째 | 5 | 7 | 8 | 12 | 2 |
4일째 | 7 | 14 | 11 | 4 | 3 |
5일째 | 9 | 7 | 14 | 8 | 4 |
=> 6 + 10 + 12 + 14 + 14 = 56 이므로 최대치가 아니게 된다.
최대치를 구하기 위해서는 성장 속도가 제일 느린 것부터 더해주어야 한다. 왜냐하면 N일 동안 초기 길이에서 성장량이 똑같이 더해지니까 몰아서 한 번에 잘라버리는 거랑 계속 자라날때마다 바로 바로 잘라오는 거랑 값은 똑같다. 그래서 매번 최대 나무를 잘라오는 것보다 성장량이 적은 조그만 나무 값이라도 더해야 값이 더 커지게 된다.
이해하기까지 꽤 걸렸지만 이해하니 구현은 바로 쉽게 할 수 있었다.
소스 코드
public class b_14247 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<Tree> list = new ArrayList<>();
int answer = 0;
int n = sc.nextInt(); //나무 개수
int[] H = new int[n]; //현재 나무 길이
int[] A = new int[n]; //자라는 길이
for(int i = 0; i < n; i++)
H[i] = sc.nextInt();
for(int i = 0; i < n; i++) {
A[i] = sc.nextInt();
list.add(new Tree(H[i], A[i]));
}
Collections.sort(list);
for(int i = 0; i < n; i++) {
//System.out.println(list.get(i).len + ", " + list.get(i).growth);
answer += list.get(i).len + (list.get(i).growth * i);
}
System.out.println(answer);
sc.close();
}
}
class Tree implements Comparable<Tree>{
int len, growth;
public Tree(int len, int growth) {
this.len = len;
this.growth = growth;
}
@Override
public int compareTo(Tree arg0) {
if(this.growth > arg0.growth)
return 1;
else if(this.growth == arg0.growth) {
if(this.len > arg0.len)
return 1;
else
return -1;
}
else
return -1;
}
}
'Algorithm > BOJ' 카테고리의 다른 글
[백준] 2805번 나무 자르기 자바 (0) | 2022.06.19 |
---|---|
[백준] 1202번 보석 도둑 자바 (0) | 2022.06.17 |
[백준] 1519번 부분 문자열 뽑기 게임 자바 (0) | 2022.06.13 |
[백준] 2075번 N번째 큰 수 자바 (0) | 2022.06.11 |
[백준] 4195번 친구 네트워크 자바 (0) | 2022.06.08 |