
처음에는 이 문제를 누적합과 투포인터를 사용해서 풀었다.
#include<iostream>
using namespace std;
int main(){
int n, k, g, point;
cin >> n >> k;
int st=0, end = k-1, mx=0, mxp =0;
int x[1000001] = {0};
int sum[1000001] = {0};
for(int i=0; i<n; i++){
cin >> g >> point;
x[point] = g;
if(mxp < point){
mxp = point;
}
}
// 누적합 구하기
for(int i=0; i<=mxp; i++){
if(i==0) sum[i] = x[i];
else sum[i] = sum[i-1] + x[i];
}
// cout << mxp <<"\n";
// for(int i=0; i<=mxp; i++){
// cout << i << " " << sum[i] <<"\n";
// }
if(mxp < k){
mx = sum[mxp];
}
while(end<=mxp){
if(end-st>k*2){
st ++;
}
//cout << st << " " << end << " " << sum[end]-sum[st-1] << "\n";
if(sum[end]-sum[st-1]> mx){
mx = sum[end]-sum[st-1];
}
end ++;
}
cout << mx <<"\n";
}
메모리: 죽을게
시간: 간당간당할게
문제점
1. 얼음 위치 배열과 누적합 배열 2개를 사용해 메모리 2배 사용
2. 누적합 생성, 탐색시 배열을 한번씩 순회 (총 2번 순회)
개선방법 : 슬라이딩 윈도우
1. 얼음 위치 배열만 사용하여 윈도우에 벗어나면 sum에서 빼주기
2. 탐색시에만 배열 순회 (총 1번 순회)
슬라이딩 윈도우란 배열이나 문자열 같은 연속된 데이터에서 고정된 크기의 창을 이동시키면서 그 안의 요소들로 특정 조건(합, 최대/최소값, 부분 문자열 등)을 효율적으로 해결하는 기법입니다. 이는 전체를 다시 계산하는 대신 창이 한 칸씩 움직일 때 양 끝의 원소만 갱신하여 중복 계산을 피하고 시간 복잡도를 O(M)으로 줄인다.
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
ios_base :: sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, k, g, x;
cin >> n >> k;
int mxp = 0;
int bucket[1000001] = {0};
for(int i=0; i<n; i++){
cin >> g >> x;
bucket[x] = g;
mxp = max(mxp, x);
}
int sum = 0, mx = 0;
int w_size = 2*k+1;
for(int i=0; i<=mxp; i++){
sum += bucket[i];
if(i>=w_size)
sum -= bucket[i-w_size];
mx = max(mx, sum);
//cout << i << " " << sum << " " << mx << "\n";
}
cout << mx <<"\n";
}
'알고리즘 > 줄울림 여름방학 알고리즘 스터디' 카테고리의 다른 글
| [BOJ/C++] 14713 앵무새(큐) (0) | 2025.12.18 |
|---|---|
| [BOJ/C++] 1940 주몽(투포인터) (0) | 2025.12.16 |
| [BOJ/C++] 11051 이항계수 2 (0) | 2025.12.09 |
| [BOJ/C++] 1713 후보 추천하기 (0) | 2025.11.27 |