디시인사이드 갤러리

마이너 갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

[풀이] 백준 17016 풀이!

ㅇㅇ(58.228) 2024.03.27 22:17:06
조회 763 추천 23 댓글 5
														

안녕하세요 블로그를 팔까 생각 중인데 마침 재밌는 문제를 최근에 해결해 풀이를 작성해봤어요 피드백 주시면 감사하겟습니당

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


 


문제 설명 (의역):

길이가 N인 양의 정수 수열이 있을때 각 최대 K개의 원소가 있는 연속부분수열들로 나눈다. 단, 연속부분수열의 갯수는 최소여야 한다. (수열의 길이가 N일때 부분수열의 갯수는 ceil(N/K)이여야 한다). 각 부분수열의 점수는 그 부분수열의 최솟값으로 정한다. 부분수열들의 점수의 합을 최대로 했을때 그 합을 구하라.


제한:

1 <= K <= N <= 1e6

1 <= 원소 값 <= 1e9


풀이:

우선 문제의 제한이 N<=1e3정도로 낮았다면 어떤 식으로 해결할 수 있을까요? 우선 정확히 ceil(N/K)개의 부분들로 나누고 싶으니, i번째 인덱스까지 나눴고 현재까지 j개의 부분들로 나눴을때 가능한 최대 합 정도로 N^2 DP 모델링이 가능하겠죠.


예제로 DP 테이블 값을 채워 보면

(개로 나눔)\(까지 나눔)

1

2

3

4

5

1

2

5

7

7

7

2

N\A

7

12

12

12







정도로 나옵니다.


여기서부터 바로 최적화를 시킬 여지가 보입니다. 그것도 그럴것이, 우리가 필요한 값은 DP[N][ceil(N/K)]의 값 뿐인데 필요 없는 상태들까지 모두 계산해주고 있기 때문입니다. 하지만 이 최적화를 구체화시키려면 조그만한 관찰이 필요합니다.


어떠한 수열에 대한 최적해를 생각해봅시다.

A[1], A[2], A[3] ... A[N-3], A[N-2], A[N-1], A[N]의 수열에서

C[1], C[2]... C[ceil(N/K)]의 나누는 포인트를 잡아야겠죠.

여기서 임의의 나누는 포인트를 잡습니다. C[i]라고 부르겠습니다. 여기서 한 주장을 하겠습니다.

i의 값은 무조건 ceil(C[i]/K)이고, N-i의 값은 무조건 ceil((N-C[i])/K)입니다.


증명:

우리의 1 순위 목표는 수열을 최소의 갯수의 부분수열로 나누는 것입니다. 점수를 최대화 하는 것은 2 순위적인 목표죠.

i의 값이 ceil(C[i]/K) 보다 크다면, i개를 쓰지 않고도 C[i]까지 분할 할 수 있기에 이는 틀린 답입니다.

i의 값이 ceil(C[i]/K) 보다 작은 상황은 한 부분수열의 원소는 K개로 한정되어 있기 때문에 모순적입니다.

N-I의 값도 비슷한 원리로 증명할 수 있습니다.


이 주장의 정당성을 증명했기에, 우리는 풀이에 결정적인 강력한 사실을 얻었습니다. i번째 인덱스까지 어떠한 수의 부분수열로 나눴을때, 사실 그 부분수열들의 갯수의 후보는 단 하나밖에 없다는 것입니다. 이를 토대로 이번엔 1차원인 DP를 모델링 할 수 있습니다.

이제 마지막으로 구현만 깔끔하게 해주면 마무리 되는데, 이 부분도 쉽지 않습니다. 여기까지 풀이를 도출한 상황에서는 어떤 방식으로 구현하든 풀리긴 하겠지만, O(N) 구현과 O(N log N)의 구현으로 갈리는거 같네요.


우선 제 구현은 O(N log N) 입니다... ㅎㅎ...


구현 설명:


수열을 ceil(N/K)개의 '블럭'으로 나눈다. 첫 번째 블록에 해당되는 인덱스들의 ceil(i/K) 값은 1이고, 두 번째 블록의 인덱스는 2이인 식으로 나눠지기 때문에 각 블럭의 DP 값은 바로 전 블럭의 DP 값으로만 구할 수 있다는 성질을 이용해 구현할 것이다.


임의의 한 블럭을 잡자. 바로 전 블럭의 DP 값은 벌써 구했다고 가정한다. 이 블럭의 i번째 원소의 DP 값을 BLOCK_DP[i] 로 부르겠고 원소의 값은 BLOCK_SEQ[i]로 부르겠다. 전 블록의 j번째 원소의 DP 값을 P_BLOCK_DP[j]로 부르겠고 원소의 값은 P_BLOCK_SEQ[j]로 부르겠다.

여기서, 어차피 우리가 고려해야 하는 구간들은 첫 번째와 두 번째의 블럭 사이에 걸쳐 있으니 BLOCK_SEQ[i]는 max(BLOCK_SEQ[I],BLOCK_SEQ[i-1])로 정의하고 (prefix max) P_BLOCK_SEQ[j]는 max(P_BLOCK_SEQ[j],P_BLOCK_SEQ[j+1])로 정의하겠다 (postfix max).

당연하게도, BLOCK_SEQ 의 값은 i가 증가할수록 증가하고 P_BLOCK_SEQ의 값은 j가 감소할수록 증가한다. 어차피 BLOCK_DP[1...K]의 값은 구해줘야 하니, i를 스위핑하면서 투 포인터로 적당히 BLOCK_SEQ과 P_BLOCK_SEQ의 최댓값을 잘 관리해주면 된다 (우선순위 큐를 이용했지만 단조성을 이용한 O(N)의 구현도 어렵진 않을거 같다).


코드:

핸들을 까기 싫었는데 숨겨도 의미 없을거 같네요.

http://boj.kr/1fa54ee8cfb140deb1a8a2301f1a28e5

 



끗!!

추천 비추천

23

고정닉 3

0

댓글 영역

전체 댓글 0
등록순정렬 기준선택
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 말머리 제목 글쓴이 작성일 조회 추천
2853 설문 연인과 헤어지고 뒤끝 작렬할 것 같은 스타는? 운영자 24/04/22 - -
44058 공지 알고리즘 대회 공부 과정 [21] 나는최고갤로그로 이동합니다. 24.04.20 1356 31
19170 공지 규칙 v2022.02.16 [8] 0xrgb갤로그로 이동합니다. 22.02.06 6332 36
1 공지 와 PS! [24] 0xrgb갤로그로 이동합니다. 18.05.28 21505 30
44249 질문 너네 코포나 대회 할 때 집중력 유지 어떻게 해 [2] ㅇㅇ갤로그로 이동합니다. 17:22 61 0
44248 일반 아까 저거 보고 풀어봣어요 멍청봇갤로그로 이동합니다. 17:09 70 0
44247 일반 코포를 거르지 않은 죄 [2] ㅇㅇ(182.231) 16:24 110 2
44246 일반 PS 공부하기전에 구문 문법 공부말한건데 [12] 수학최종보스갤로그로 이동합니다. 16:14 199 0
44245 일반 싸다구 글 읽고 [2] ㅇㅇ(223.38) 16:04 170 0
44244 일기 드갔으면 조졌을뻔했군 [4] EN_SA갤로그로 이동합니다. 15:50 131 0
44243 일반 처음으로 매개 변수 탐색 한번에 맞췄음 ㅇㅇ(182.215) 15:16 60 0
44242 일반 나만 안풀리면 산책함? [3] ㅇㅇ(59.29) 15:09 92 0
44241 일반 진짜 어렵네 이거 [4] ㅇㅇ(106.101) 12:14 220 0
44240 일기 다익스트라 원리까진알겠는데 [12] ㅇㅇ(183.104) 09:19 298 0
44239 일반 이거 어디서 예외처리 오류가 나는거임?? [11] 수학최종보스갤로그로 이동합니다. 08:17 262 0
44238 일반 초반 배치때 레이팅 더 올리고 싶으면 [2] ㅇㅇ(221.151) 03:37 172 0
44237 일반 div2E/div1C 증명 부분이 이해가 안됩니다 ㅇㅇ(1.210) 03:27 80 0
44236 일반 딥2D 딥1B같은 문제 빠르게 푸려면 어떻게 공부해야함? [5] ㅇㅇ(61.43) 02:14 190 0
44235 일반 Div2 12등 [3] 그레도라갤로그로 이동합니다. 02:04 310 10
44234 일반 그래서 이번에 대회에서 가져온 문제가 뭐임? [1] ㅇㅇ(115.92) 02:03 161 0
44233 일반 아오 1D 풀이 거의 맞았었네 biximo갤로그로 이동합니다. 02:00 83 0
44232 일반 이번 1C 비슷한문제 [4] dpk갤로그로 이동합니다. 01:56 168 0
44231 일반 Div2D, Div1B 비슷한 문제 biximo갤로그로 이동합니다. 01:49 78 0
44230 일반 Div2e어케함? ㅇㅇ(223.38) 01:47 57 0
44229 일반 아 visual studio 부술뻔 [2] ㅇㅇ(1.249) 01:46 154 0
44228 일반 C 그리디 맞아요? [10] ㅇㅇ(58.125) 01:42 208 0
44227 일반 레드간다 ㅋㅋㅋㅋㅋㅋㅋㅋ [14] dpk갤로그로 이동합니다. 01:40 421 17
44226 일반 아오 D 구현 못 끝냈네 biximo갤로그로 이동합니다. 01:35 84 0
44224 일반 특성화고인데 우리 학교 쌤 백준 30몇위심 [4] ㅇㅇ(121.138) 00:44 304 0
44222 일반 코테 노베인데 공부계획 하자 없는지 체크좀 해주셍.. [4] ㅇㅇ(123.214) 04.27 159 0
44221 질문 2차원 좌표간 거리 시간복잡도 줄이기 [2] ㅇㅇ(112.165) 04.27 180 0
44220 일반 문제를 재사용했다고? [1] ㅇㅇ(119.194) 04.27 191 1
44219 일반 디코 급식 또 등장 [5] ㅇㅇ(58.29) 04.27 327 7
44218 일반 45도 돌려서 푸는거 왤케 안 떠오르지 ㅇㅇ(125.129) 04.27 103 0
44217 일반 앳코더 스무스 하구만 [1] ㅇㅇ(221.151) 04.27 99 0
44216 일반 근데 여기 [5] ㅇㅇ(106.102) 04.27 338 0
44215 질문 이게 왜 메모리 초과가 남? [1] ㅇㅇ(210.105) 04.27 129 0
44214 일반 구현 딸려서 바킹독 시뮬레이션 문제집 다 풀려고 봤는데 ㅇㅇ(58.237) 04.27 115 0
44212 일반 드디어 400문제 풀었다 [4] 코더(59.16) 04.27 193 0
44211 일반 오늘 앳코더 배점 뭐냐 [1] ㅇㅇ(221.144) 04.27 169 0
44210 일반 Ps관련 대화할때 싸다구마려운 대화법 정리 [15] ㅇㅇ(118.235) 04.27 856 37
44209 일반 코린이 간단한 질문 하나만 알려줘 고수 형들 [3] ㅇㅇ(211.234) 04.27 172 0
44208 일반 오늘 치팅 잡기 쉬울거 같은데 [2] ㅇㅇ(211.234) 04.27 272 0
44207 일반 백준 실5 응애입니다 하루 몇문제 페이스로 가시나요 보통 [2] ㅇㅇ(116.39) 04.27 203 0
44206 일반 std::map 사용하는 문제 추천 좀... [6] ㅇㅇ(61.43) 04.27 231 0
44205 일반 백준 반평면 땅따먹기2 맞왜틀 제발 살려다오 7시간째 이유를 못 찾는중 [10] ㅇㅇ(121.55) 04.27 317 0
44204 일반 이것도 치팅임? [4] ㅇㅇ(124.53) 04.27 351 0
44203 일기 클래스4들어오니깐 좀 빡센느낌이네 [2] ㅇㅇ(183.104) 04.27 196 0
44202 일반 난 절대 코포를 거르지 않아 [6] ㅇㅇ(182.231) 04.26 328 2
44201 일반 뭔가 실력이 느는거 같아서 뿌듯하다 [3] ㅇㅇ(220.76) 04.26 203 4
44200 일반 내일 코포 진자 걸러야 되나... [4] biximo갤로그로 이동합니다. 04.26 309 0
44199 일반 오늘부터 다시 PS 열심히 한다 [4] ㅇㅇ(218.48) 04.26 347 1
44198 일반 종만북 백준 [5] ㅇㅇ(211.234) 04.26 227 1
44197 일반 피갤컵보다 시급한거 [6] Raciel갤로그로 이동합니다. 04.26 426 2
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2