Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 27 | 28 |
Tags
- GatherTown
- 이젠 골드구현도 어렵네..
- 네트워크플로우
- spring
- 알고리즘
- 재귀함수
- 완전탐색
- 백준코딩테스트
- 자바PS
- 백준
- COSPRO
- PS
- 우선순위큐
- 구현
- deque
- 01BFS
- QUICKSTARTGUIDE
- 세그먼트트리
- dp
- BFS
- DFS
- 취득후기
- 다익스트라
- 다이나믹프로그래밍
- 시뮬레이션
- java
- 게더타운시작
- YBMCOS
- COSPROJAVA1급
- 엘라스틱서치
Archives
- Today
- Total
공부공간
BOJ - 12846 ) 무서운 아르바이트 본문
https://www.acmicpc.net/problem/12846
12846번: 무서운 아르바이트
성화는 악독하기로 유명한 편의점 사장이다. 그의 편의점에는 특이한 임금 체계를 가지고 있다. 각 날마다 일의 차이때문에 일마다 급여가 정해져 있다. 돈은 당일에 주지 않고 퇴직을 할 때 한
www.acmicpc.net
연속한 수열에서 가장 최솟값을 기준으로 얻을 수 있는 총합의 가장 큰 값을 고르는 문제이다.
문제상황을 잘 읽어보면,
https://www.acmicpc.net/problem/6549
6549번: 히스토그램에서 가장 큰 직사각형
입력은 테스트 케이스 여러 개로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있고, 직사각형의 수 n이 가장 처음으로 주어진다. (1 ≤ n ≤ 100,000) 그 다음 n개의 정수 h1, ..., hn (0 ≤ hi ≤
www.acmicpc.net
이 문제와 완전한 동치임을 알 수 있다. 즉 가장 큰 직사각형의 넓이를 구하기위해,
밑변을 세그먼트트리의인덱스로 설정하고 해당 수열에서 가장 낮은 ( 높이를 결정하는 ) 값의 인덱스를
세그먼트 트리에 넣어두었다.
또한 재귀함수를 통하여, 밑변의 길이가 1인 직사각형까지 모두 탐색한다.
즉, 연속된 날짜에 아르바이트를 하더라도, 가장 낮은임금을 기준으로 급여를 받기 때문에,
가장 낮은 임금의 인덱스를 저장하며 직사각형처럼 풀어준다.
재귀의 다음 STEP으로는 현재 인덱스의 좌우를 변수로 주어탐색한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class 무서운아르바이트 {
public static int n;
public static int arr[];
public static int seg[];
public static long answer = -1;
public static int out = 987654321;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
arr = new int[n]; seg=new int[4*n];
for(int i=0;i<n;++i) {arr[i]=Integer.parseInt(st.nextToken());}
seginit(1,0,n-1);
dfs(0,n-1);
System.out.println(answer);
}
private static void dfs(int s, int e) {
if(e<s)return;
if(s==e) {
long res = arr[e];
answer = answer > res ? answer : res;
return ;
}
int index = findmin(1,0,n-1,s,e);
long res = (long)(e-(s-1)) * (long)arr[index];
answer = answer > res ? answer : res;
dfs(s,index-1);
dfs(index+1,e);
}
private static int seginit(int now, int s, int e) {
// 구간의 가장작은 높이의 인덱스를 저장
if(s==e) {return seg[now] = s;}
else {
int l = seginit(now*2,s,(s+e)>>1);
int r = seginit(now*2+1,((s+e)>>1)+1,e);
return (seg[now] = (arr[l]>arr[r]?r:l));
}
}
private static int findmin(int node, int l, int r , int s , int e) {
if(r < s || e < l) return out;
else if( s <= l && r<= e) return seg[node];
int rr = findmin(2*node, l, (r+l)>>1, s, e);
int ll = findmin(2*node+1, ((r+l)>>1)+1, r, s, e);
if(rr==out && ll!= out) return ll;
if(rr!=out && ll== out) return rr;
// 둘다 out인경우가? 존재할수 없다
return arr[rr] > arr[ll] ? ll : rr ;
}
}
'알고리즘 > SegmentTree' 카테고리의 다른 글
BOJ - 1306 ) 달려라 홍준 (0) | 2021.07.27 |
---|---|
BOJ - 6549 ) 히스토그램에서 가장 큰 직사각형 (0) | 2020.10.28 |
BOJ -2268 ) 수들의 합 (0) | 2020.05.17 |
BOJ - 10868 ) 최솟값 (0) | 2020.05.16 |
BOJ - 2357 ) 최솟값과 최댓값 (0) | 2020.05.16 |
Comments