문제
- 문제 링크
BOJ 30461 - 낚시
$N*M$개의 칸 각각에 존재하는 물고기의 정보가 주어진다.
$Q$개의 쿼리에 대해, 미끼를 회수할 때까지 몇 마리의 물고기가 사로잡히는지 출력하자.
TL : $2$ sec, ML : $1024$ MB
$1 ≤ N,M ≤ 2,000$ $1 ≤ Q ≤ 300,000$ $0 ≤ a_{ij} ≤ 500$
알고리즘 분류
- 다이나믹 프로그래밍 (dp)
- 누적 합 (prefix_sum)
풀이
$dp[i][j]$에 $Q(i, j)$의 답을 저장한다고 생각해보자.
계단식으로 답을 계산할 수 있으므로, 먼저 $dp[i][j]$는 $dp[i - 1][j - 1]$을 포함한다.
여기에 추가적으로 $A[i][j] + A[i - 1][j] + A[i - 2][j] + ... + A[1][j]$ 을 포함해야 하는데, 이 역시 $dp$에 기록된 값을 이용해 다음과 같이 정리할 수 있다.
$A[i][j] + dp[i - 1][j] - dp[i - 2][j - 1]$.
이를 모든 $A_{ij}$에 대해 전처리해 두면, 쿼리당 $O(1)$에 응답할 수 있다.
전체 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include<bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(0); cin.tie(0); int n, m, q; cin >> n >> m >> q; int dp[2001][2001]{}; for (int i(1); i <= n; i++) for (int j(1); j <= m; j++) { int x; cin >> x; dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j] + x; dp[i][j] -= dp[max(0, i - 2)][j - 1]; } for (int i, j; q--;) { cin >> i >> j; cout << dp[i][j] << '\n'; } } | cs |
comment
끝
'Problem Solving > Baekjoon Online Judge (Gold)' 카테고리의 다른 글
백준 30621 - 어? 금지 (C++) (1) | 2023.11.14 |
---|---|
백준 30622 - Rush & Slash (C++) (1) | 2023.11.14 |
백준 30464 - 시간낭비 (C++) (3) | 2023.11.06 |
백준 25606 - 장마 (C++) (1) | 2023.10.18 |
백준 29811 - 지각하기 싫어 (C++) (0) | 2023.09.17 |