문제 원본 : https://www.acmicpc.net/problem/5721
5721번: 사탕 줍기 대회
입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 M과 N이 주어졌다. (1 ≤ M × N ≤ 105) 다음 M개 줄에는 박스에 들어있는 사탕의 개수 N개가 주어진다. 박스에 들
www.acmicpc.net
import java.io.*;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st;
StringBuilder builder = new StringBuilder();
int m, n;
int[][] candy;
int[] rowCandy, rowDp, colDp;
while (true) {
st = new StringTokenizer(br.readLine());
m = Integer.parseInt(st.nextToken());
n = Integer.parseInt(st.nextToken());
if (m == 0 && n == 0) {
break;
}
candy = new int[m][n];
rowCandy = new int[m];
rowDp = new int[m];
colDp = new int[n];
for (int i = 0; i < m; ++i) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; ++j) {
candy[i][j] = Integer.parseInt(st.nextToken());
}
}
for (int i = 0; i < m; ++i) {
colDp[0] = candy[i][0];
if (n > 1) {
colDp[1] = Math.max(candy[i][0], candy[i][1]);
}
for (int j = 2; j < n; ++j) {
colDp[j] = Math.max(colDp[j - 1], colDp[j - 2] + candy[i][j]);
}
rowCandy[i] = colDp[n - 1];
}
rowDp[0] = rowCandy[0];
if (m > 1) {
rowDp[1] = Math.max(rowCandy[0], rowCandy[1]);
}
for (int i = 2; i < m; ++i) {
rowDp[i] = Math.max(rowDp[i - 1], rowDp[i - 2] + rowCandy[i]);
}
builder.append(rowDp[m - 1]).append("\n");
}
bw.write(builder.toString());
bw.close();
br.close();
}
}
- 다이내믹 프로그래밍 문제
- 아이디어 참고
- 기본 점화식은 dp[i] = Max(dp[i - 1], dp[i - 2] + candy[i])
- 각 행마다 최댓값을 구한 뒤, 그 최댓값의 배열을 다시 동일한 점화식으로 풀면 된다.
'알고리즘 > BOJ' 카테고리의 다른 글
| [BOJ] 3273. 두 수의 합 (0) | 2022.04.09 |
|---|---|
| [BOJ] 4781. 사탕 가게 (0) | 2022.04.08 |
| [BOJ] 1976. 여행 가자 (0) | 2022.04.06 |
| [BOJ] 2470. 두 용액 (0) | 2022.04.05 |
| [BOJ] 1715. 카드 정렬하기 (0) | 2022.04.04 |