https://www.acmicpc.net/problem/11659
for (int i = 0; i < m; i++) { //m번 정답을 구해야 함
int from, to;
cin >> from >> to;
int answer=0;
for(int j=from;j<=to;j++) { // 그 때마다 직접 배열에 접근하여 구해줌
answer+=arr[j];
}
cout << answer << "\n";
}
=> 이 경우의 시간 복잡도 O(n^2) , 최대 n = 100000
=> 100,000,000 = 1초 정도로 추정
=> 시간 제한 1초 안에 수행이 어려움
=> for문 하나여야 함
따라서 DP를 사용해서, 배열 값을 입력함과 동시에 합 값을 구해서 이후 반복적인 값들을 바로 재사용하도록 함
=> For 문이 하나이므로 O(n)
합의 최댓값 : 1000 * 100000 = 100,000,000
=> vector 내부의 값은 int로 써도 무방
메모리 최댓값 : 4 * 100000
#include <iostream>
#include <vector>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, m;
cin >> n >> m;
vector<int> v(n + 1);
v[0] = 0;
for (int i = 1; i <= n; i++) {
int input = 0;
cin >> input;
v[i]=v[i-1]+input; //
}
for (int i = 0; i < m; i++) {
int from, to;
cin >> from >> to;
cout << (v[to] - v[from - 1]) << "\n";
}
return 0;
}
https://www.acmicpc.net/problem/11660
기본 접근 방식은 1차원 배열의 위의 문제와 동일
v[i][j] : (i,j) 원소까지의 누적합
=> 누적합 자체를 어떻게 계산할지가 문제임
v[i][j]의 값을 구하는 과정을 이해하기
위에서 (3,3) 위치의 5 원소까지의 누적합은 어떻게 구할 수 있을까?
정해진 직사각형들로 사각형의 넓이를 구한다고 생각하면 좋다
(i,j-1)까지의 누적합 직사각형(파랑) 과 (i-1,j) 까지의 누적합(노랑), 그리고 5를 더해주면 된다
여기서 주의할 점은 (i-1,j-1) 까지의 누적합(초록) 부분이 두번 더해진다는 것이다. 그 부분을 마지막에 빼줘야 한다
v[i][j] = v[i - 1][j] + v[i][j - 1]-v[i-1][j-1]+ input;
그럼 위의 이 식이 나온다
이 값을 v 배열에 넣어주면 된다
위의 기본 원리와 동일하다.
(2,2) 부터 (4,4) 까지의 합을 구하는 경우
분홍+파랑+노랑-초록 을 해주면 되는 것이다
v[toX][toY] - v[toX][fromY-1] - v[fromX-1][toY] + v[fromX-1][fromY-1]
이것을 그냥 코드로 구현해주기만 하면 된다
#include <iostream>
#include <vector>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, m;
cin >> n >> m;
vector<vector<int>> v(n+1);
for (int i = 0; i <= n; i++) {
v[i].resize(n+1);
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
int input;
cin >> input;
v[i][j] = v[i - 1][j] + v[i][j - 1]-v[i-1][j-1]+ input;
}
}
for (int i = 0; i < m; i++) {
int fromX, fromY, toX, toY;
cin >> fromX >> fromY >> toX >> toY;
//cout << v[toX][toY] << " - " << v[toX][fromY-1] <<" - " << v[fromX-1][toY] <<" + " << v[fromX-1][fromY-1] << " = ";
cout << (v[toX][toY] - v[toX][fromY-1] - v[fromX-1][toY] + v[fromX-1][fromY-1]) << "\n";
}
}