백준[파이썬]
[백준/Python] - 11660 구간 합 구하기 5
코린이 파닥거리기
2025. 5. 14. 22:15
728x90
반응형
SMALL
https://www.acmicpc.net/problem/11660
제출코드
import sys
input = sys.stdin.readline
N , M = map(int,input().split())
N_list = []
dp = [[0] *(N+1) for _ in range(N+1)]
for _ in range(N):
N_list.append(list(map(int,input().split())))
for i in range(1,N+1):
for j in range(1,N+1):
dp[i][j] = dp[i][j-1] + dp[i-1][j] - dp[i-1][j-1] + N_list[i-1][j-1] # i = 1 j = 2 N_list[0][2] => 2
for _ in range(M):
x1,y1,x2,y2 = map(int,input().split())
ans = dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1]
print(ans)
문제 접근은
구간별로의 합을 전부 구한 뒤 나머지의 구간들을 빼서 답을 구한다라고 접근은 맞게 했는데
이걸 DP를 사용해서 구해야하는지 몰랐다....
나머지 구간들을 어떻게 빼야하고 구간 합을 어떻게 다 더해야 하는지도 몰라서 접근만 맞게했다...
일단 1부터 시작하기 위해 dp를 확장해서 0인 행과 0인 열을 0으로 초기화한다.
해당 테이블에서 보자
우리가 원하는 값은 8이라고 했을 때
이전 행에서의 누적 합 이전 열에서의 누적합을 더한다.
그런데 여기서
이전 행 : 3 = 2 + 1
이전 열 : 3 = 2 + 1 이 된다.
그럼 1을 두번 더하는 것이므로 누적합에 1을 빼줘야된다는 것이다.
그래서
이전 행 + 이전 열 - 이전 행과 열 + 해당 N_list의 원소값을 더해주면 해당 2,2까지의 누적합은 8이 되는 것이다.
그리고 구간 합을 구할때는 반대로 생각하면 된다.
끝 구간 까지의 합을 구하고, x1과 y1이전 까지의 누적합을 빼주면 된다.
[x1-1][y2] ==> x1 이전 행 까지의 누적 합
[x2][y1-1] ==> y1 이전 행 까지의 누적 합
그런데 여기서도 겹치는 부분이 생긴다. 그건 [x1-1][y1-1]부분이므로 이 값을 더해줘야지 구간 합이 성립이 된다.
정말 백준문제를 풀면서 계속 느끼는건데 문제 만든사람도 천재고
문제를 푸는사람도 대단하다고 느낀다...
728x90
반응형
LIST