PS/BOJ

[백준 BOJ][DP] 2167 2차원 배열의 합

Jubil 2018. 8. 21. 00:52
반응형

2167_2차원 배열의 합

링크

https://www.acmicpc.net/problem/2167

 

풀이


 

DP[i][j] (1 <= i, j <= 300)을 구간 [1, 1] ~ [i, j]의 합이라고 정의합니다.

 


 

DP[1][4]입니다.

 


 

DP[3][2]입니다.

 

그렇다면 DP[i][j]를 구하는 방법을 알아보겠습니다.


 

DP[i][j] = DP[i-1][j] + DP[i][j-1] – DP[i-1][j-1] + arr[i][j]

두 개의 구간합에서 겹치는 부분을 빼주고 자신을 더하는 방식으로 구할 수 있습니다.

 

 

그렇다면 이 구간합을 가지고 어떻게 답을 구할 수 있을까요?

 

예를 들어 (3, 3) ~ (4, 5)의 구간합을 구한다고 생각해봅시다.

 


 

(1, 1) ~ (4, 5)의 합에서 좌측과 상단을 쳐내고 두 번 겹친 DP[2][2]를 다시 더해줌으로써 구할 수 있습니다.

일반화하면 (j, i) ~ (y, x)의 합을 구하고 싶다면,

DP[y][x] ((1, 1) ~ (y, x)의 합에서) – DP[y][i - 1] (좌측을 쳐내고) - DP[j - 1][x] (우측을 쳐내고) + DP[j-1][i-1] (두 번 쳐낸 곳을 더해 줌)이라는 식으로 답을 구할 수 있습니다.

 

코드

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

//2167_2차원 배열의 

#include <cstdio>

#include <algorithm>

using namespace std;

 

int DP[301][301], n, m, k, i, j, x, y, tmp;

 

int main() {

    scanf("%d %d"&n, &m);

 

    for (int i = 1; i <= n; ++i) {

        for (int j = 1; j <= m; ++j) {

            scanf("%d"&tmp);

            DP[i][j] = DP[i - 1][j] + DP[i][j - 1- DP[i - 1][j - 1+ tmp;

        }

    }

 

    scanf("%d"&k);

 

    while (k--) {

        scanf("%d %d %d %d"&j, &i, &y, &x);

        printf("%d\n", DP[y][x] - DP[y][i - 1- DP[j - 1][x] + DP[j-1][i-1]);

    }

    

    return 0;

}

Colored by Color Scripter

cs




반응형

'PS > BOJ' 카테고리의 다른 글

[백준 BOJ] 1009 분산처리  (0) 2018.10.27
[백준 BOJ] 1002 터렛  (0) 2018.10.26
[백준 BOJ][DP] 9465 스티커  (0) 2018.08.21
[백준 BOJ][DP] 1149 RGB거리  (0) 2018.07.28
[백준 BOJ][map] 1764 듣보잡  (0) 2018.07.26