문제
https://www.acmicpc.net/problem/13904
개념
그리디, 정렬, 우선순위 큐
코드 설명
그리디 알고리즘을 이용해 풀 수 있습니다. 가장 큰 점수를 구하기 위해서는 최대한 큰 점수의 과제부터 처리하되, 가능한 가장 늦은 날짜에 배정해야만 대한 많은 과제를 수행하고 높은 점수를 얻을 수 있기 때문입니다.
문제의 요구사항을 분석하면 다음과 같습니다.
- 하루에 한 과제만 할 수 있습니다.
- 과제는 마감일 전에만 수행할 수 있습니다.
- 목표는 얻을 수 있는 점수의 최댓값을 구하는 것입니다.
이를 해결하기 위한 알고리즘의 핵심 아이디어는 다음과 같습니다.
- 정렬 방식: 점수 기준 내림차순으로 정렬합니다. 마감일에 따라 높은 점수의 과제부터 할당
- 스케줄 배열 사용: scedule 배열을 사용하여 각 날짜별에 수행하는 과제에 대한 점수를 저장
- 과제 할당 방식: 각 과제에 대해, 마감일부터 역순으로 가장 늦은 가능한 날짜에 할당하도록 함
이 방식으로 예제를 처리하면 스케줄 배열에 원소를 다음과 같이 할당할 수 있습니다.
먼저 문제에서 제시한 입력 예시는 다음과 같습니다.
7
4 60
4 40
1 20
2 50
3 30
4 10
6 5
이를 스케쥴 배열에 할당하면 다음과 같은 테이블로 표현할 수 있습니다.
1 | 2 | 3 | 4 | 5 | 6 | 7 |
30 | 50 | 40 | 60 | 5 |
이런식으로 접근하면 결과적으로 60 + 50 + 40 + 30 + 5 = 185점이라는 최대 점수값을 얻게 됩니다.
틀렸던 이유 😭
hwInfo.sort((a, b) => {
if (a[0] === b[0]) {
return b[1] - a[1]; // 마감일이 같으면 점수 기준 내림차순 정렬
}
return a[0] - b[0]; // 마감일 기준 오름차순 정렬
});
틀렸던 코드에서는 점수를 오름차순 정렬했는데, 점수가 큰 것부터 스케줄 배열에 넣어야 하므로
내림차순으로 정렬해야 합니다! b[0] - a[0]로 바꾸어서 해결했습니다.
정답 코드(JavaScript)
const fs = require('fs');
// 백준 제출용
// let input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
// 로컬 테스트용
const filePath =
process.platform === 'linux' ? 'dev/stdin' : __dirname + '/input.txt';
let input = fs.readFileSync(filePath).toString().trim().split('\n');
// 백준 13904번: 과제
const n = Number(input[0]);
const hwInfo = input.slice(1).map((v) => v.split(' ').map(Number));
hwInfo.sort((a, b) => {
if (a[1] === b[1]) {
return b[0] - a[0]; // 점수가 같다면 마감일 기준 내림차순 정렬
}
return b[1] - a[1]; // 점수 기준 내림차순 정렬
});
let maxDay = Math.max(...hwInfo.map((v) => v[0])); // 가장 늦게 끝나는 과제 마감일(최대값)
let totalScore = 0;
const scedule = new Array(maxDay + 1).fill(0); // 날짜별 과제 점수 저장 배열
for (const [d, w] of hwInfo) {
// 마감일부터 처리
for (let i = d; i > 0; i--) {
// 해당 날짜에 과제가 없으면 점수 저장
if (scedule[i] === 0) {
scedule[i] = w;
totalScore += w;
break;
}
}
}
console.log(totalScore);
- 내림차순 정렬
- 과제를 점수(w) 기준으로 내림차순 정렬합니다.
- 점수가 같을 경우 마감일(d) 기준으로 내림차순 정렬합니다.
- 스케쥴 배열 할당
scedule
배열을 사용하여 각 날짜에 배정된 과제의 점수를 저장합니다.- 각 과제에 대해 마감일부터 역순으로 가능한 가장 늦은 날짜에 배정합니다
- 해당 날짜에 할당된 과제가 없으면, 점수를 저장하고 다음 단계로 넘어갑니다.
'PS' 카테고리의 다른 글
[백준] 11053번: 가장 긴 증가하는 부분 수열 (JavaScript) (0) | 2025.02.21 |
---|---|
[백준] 1062번: 연결 요수의 개수 (JavaScript) (0) | 2025.02.20 |
[백준] 11659번: 구간 합 구하기 4 (JavaScript) (0) | 2025.02.19 |
[SWEA] 6808번: 규영이와 인영이의 카드게임 (Java) (0) | 2025.02.18 |
[백준] 15926번: 현욱은 괄호왕이야!! (JavaScript) (0) | 2025.02.16 |