https://school.programmers.co.kr/learn/courses/30/lessons/92344
1. 구간합 효율적으로 구하는법
1.1 1차원예시
[ 0 , 0 , 0 , 0 , 0] 에 0~3idx까지 a를 더하고싶다
1. [a, 0, 0, 0, -a] 배열 생성
2. ->쪽으로 누적합을구함
3. a배열과 원본배열을 더함. 끝.
1.2 2차원예시
네모친구간에 a를 더하고싶다.
1. 좌측위, 우측아래에 a를 더하고 / 우측위, 좌측아래에 -a를 더한다.
2. ->, 아래쪽으로 누적합을구함
3. 그결과과 원본을 더함. 끝.
2. 전체코드
#include <bits/stdc++.h>
using namespace std;
int a[1004][1004],ret;
int solution(vector<vector<int>> board, vector<vector<int>> skill) {
int n=board.size();
int m=board[0].size();
//1. 누적합배열생성
//where out of index? -> a를 크게선언[1004]했으므로 상관없음!
for(auto v : skill){
int type=v[0], r1=v[1],c1=v[2],
r2=v[3],c2=v[4],degree=v[5];
if(type==1) degree= -degree;
a[r1][c1]+=degree;
a[r2+1][c2+1]+=degree;
a[r1][c2+1]-=degree;
a[r2+1][c1]-=degree;
}
//누적합더하기 ->, 아래
for(int i=0;i<n;++i){
for(int j=1;j<m;++j){
a[i][j]+=a[i][j-1];
}
}
//누적합더하기 아래
for(int i=1;i<n;++i){
for(int j=0;j<m;++j){
a[i][j]+=a[i-1][j];
}
}
//board와 a 더하기
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
board[i][j]+=a[i][j];
}
}
//1이상인 갯수세기
int ret=0;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(board[i][j]>=1) ret++;
}
}
return ret;
}
'Algorithm > dp' 카테고리의 다른 글
백준 11057 오르막수 c++ // dp (0) | 2024.04.08 |
---|---|
백준 14501 퇴사 c++ // dfs, dp, 트리하부호출 되는경우만 dfs실행 (0) | 2024.03.20 |
프로그래머스 보행자천국 c++ // dp, 경우의수는 dp를 의심하라. (0) | 2023.12.07 |
백준 2565 전깃줄 c++ // dp, LIS(최장부분증가수열) 풀이 (0) | 2023.12.01 |
백준 2748 피보나치수2 c++ // 탑다운 dp 형식 (0) | 2023.11.30 |