[Gold IV] 점수따먹기 - 1749
성능 요약
메모리: 19256 KB, 시간: 892 ms
❌ 접근 방법. 완탐
➡️ 해당 풀이법의 시간 복잡도 :
당연히 시간복잡도 초과
⭕ 접근 방법. 누적합
(1, 1) ~ (x ,y)까지의 누적합을 구한 후 구간에서 최대를 찾는다.
(x, y)를 입력 받으면서 누적 합을 저장한다.→
아래 사진 참고
만들 수 있는 구간을 모두 탑색하며 최대 값을 찾는다. →
구간 합은 아래와 같이 구할 수 있다.
matrixSum[endR][endC] - matrixSum[startR - 1][endC] - matrixSum[endR][startC - 1] + matrixSum[startR - 1][startC - 1]
➡️ 해당 풀이법의 시간 복잡도 :
구간의 합이 최대
가 될때 그 최대값을 출력하는 문제이다. 단 , 배열이 1차원import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int N; // 행의 개수
static int M; // 열의 개수
static int matrix[][]; // 입력으로 주어지는 행렬
static int matrixSum[][]; // 행렬의 누적 합을 저장하는 배열
static int max = Integer.MIN_VALUE; // 최댓값을 저장하는 변수
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
matrix = new int[N + 1][M + 1];
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 1; j <= M; j++) {
matrix[i][j] = Integer.parseInt(st.nextToken());
}
}
matrixSum = new int[N + 1][M + 1];
// 행렬의 누적 합 계산
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
matrixSum[i][j] = matrixSum[i][j - 1] + matrixSum[i - 1][j] + matrix[i][j] - matrixSum[i - 1][j - 1];
}
}
// 모든 부분 행렬의 합 중 최댓값 찾기
for (int startR = 1; startR <= N; startR++) {
for (int startC = 1; startC <= M; startC++) {
for (int endR = startR; endR <= N; endR++) {
for (int endC = startC; endC <= M; endC++) {
max = Math.max(max, matrixSum[endR][endC] - matrixSum[startR - 1][endC] - matrixSum[endR][startC - 1] + matrixSum[startR - 1][startC - 1]);
}
}
}
}
System.out.println(max);
}
}