Back to : algorithms
  • ๋‚œ์ด๋„ : Diamond 4
  • ์ถœ์ฒ˜ : Singapore National Olympiad in Informatics, 2018 - 5๋ฒˆ
Contents

Thinking ํŒŒํŠธ๊ฐ€ ๋๋‚œ ํ›„์—๋„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ• ์ง€ ์ •๋ง ๋งŽ์€ ๊ณ ๋ฏผ์„ ํ–ˆ๊ณ , ๊ฒฐ๊ตญ ๊ตฌํ˜„์„ ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ•ด์„œ ๋‹ค๋ฅธ ์‚ฌ๋žŒ ๊ตฌํ˜„์„ ์ฐธ๊ณ ํ–ˆ๋‹ค. ๊ตฌํ˜„ ํŠธ๋ฆญ์ด ์ƒ๋‹นํžˆ ๋ฐฐ์šธ์ ์ด ๋งŽ์•˜๋‹ค.

ํ’€์ด

์ฃผ์–ด์ง„ ๋ฌธ์ œ๋ฅผ formulateํ•˜๋ฉด, ๊ฐ element๊ฐ€ $S$ ์ดํ•˜์ธ $N$๊ฐœ์งœ๋ฆฌ sequence์— increment ๋˜๋Š” decrement ํ•˜๋Š” ์—ฐ์‚ฐ์„ ์ตœ์†Œํ•œ์œผ๋กœ ํ•ด์„œ, $\abs{a_i - a_{i-1}} \leq H$ ๊ฐ€ ๋˜๊ฒŒ ํ•˜๊ณ ์ž ํ•  ๋•Œ ํ•„์š”ํ•œ ์ตœ์†Œ ํšŸ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ์ด๋‹ค.

๋จผ์ €, ๋‹ต์ด ๋˜๋Š” sequence๋ฅผ $b_i$ ๋ผ๊ณ  ํ•˜๊ณ , $a_i$๋ฅผ $b_i$๋กœ ๋ฐ”๊พธ๋ ค๊ณ  ํ•œ๋‹ค๊ณ  ํ•˜์ž. ์ด๋•Œ, ๊ด€์ฐฐํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์‹ค์€, ํ˜„์žฌ ๊ฐ€์žฅ ํฐ element๋ณด๋‹ค $b_i$๊ฐ€ ๋” ์ปค์ ธ์•ผ ํ•  ์ด์œ ๊ฐ€ ์ „ํ˜€ ์—†๋‹ค. (๊ฑฐ์˜ ์ž๋ช…ํ•˜๋‹ค)

Subtask 1, 2, 5 (+13์ )

$b_i$ ๋Š” $S$ ์ดํ•˜์ด๋ฏ€๋กœ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ DP ํ…Œ์ด๋ธ”์„ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

dp[i][j] : a[1]...a[i] ๊นŒ์ง€๋งŒ ๊ณ ๋ คํ•˜๊ณ , b[i] = j๊ฐ€ ๋˜๋„๋ก ํ•  ๋•Œ ํ•„์š”ํ•œ ์ตœ์†Œ ํšŸ์ˆ˜

์ด DP ํ…Œ์ด๋ธ”์„ ์ƒ๊ฐํ•ด ๋ณด๋ฉด, dp[i][j]๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ ์ž ํ•  ๋•Œ, dp[i-1][*]์˜ ์ •๋ณด๋งŒ ์žˆ์œผ๋ฉด ๋œ๋‹ค. ๊ตฌ์ฒด์ ์œผ๋กœ, ์ˆ˜์—ด์˜ $i-1$๋ฒˆ์งธ๊ฐ€ $k$์ผ ๋•Œ, $i$๋ฒˆ์งธ๊ฐ€ $j$๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š”์ง€๋ฅผ ๋จผ์ € ์•Œ์•„์•ผ ํ•˜๊ณ , ๋งŒ์•ฝ ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ํ˜„์žฌ $a_i$๋ฅผ $j$๊นŒ์ง€ ๋ฐ€์–ด์•ผ ํ•œ๋‹ค. ์ฆ‰, ๋‹ค์Œ๊ณผ ๊ฐ™์€ transition์„ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

\[dp(i, j) = \min_{j-h \leq k \leq j + h} dp(i-1, k) + \abs{a_i - j}\]

๋‹น์—ฐํžˆ, $j-h$ ๋‚˜ $j+h$ ๋ฒ”์œ„๊ฐ€ $0$์ด๋‚˜ $S$๋ฅผ ๋„˜์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค. ์ด DP ํ…Œ์ด๋ธ”์„ ๊ทธ๋ƒฅ ๊ทธ๋Œ€๋กœ ๊ณ„์‚ฐํ•˜๋ฉด $O(NSH)$ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๊ณ , $O(NS)$์นธ ํ…Œ์ด๋ธ”์ด ํ•„์š”ํ•˜๋‹ค. ๋ชจ๋“  ๊ฐ๊ฐ์˜ ์š”์†Œ๊ฐ€ ์ž‘๊ฒŒ control๋˜์–ด ์žˆ๋Š” 1, 2, 5๋ฒˆ ์„œ๋ธŒํƒœ์Šคํฌ๋ฅผ ์ด DP๋กœ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•˜๋‹ค.

Subtask 4 (+5์ )

$H = 0$์ผ ๋•Œ๋Š”, ๊ฒฐ๊ตญ $a_i$๋“ค์„ ๋ชจ๋‘ ๋˜‘๊ฐ™์ด ๋งž์ถฐ์•ผ ํ•˜๋ฉฐ, $a_i$ ๋“ค ์ค‘ ์ค‘๊ฐ„๊ฐ’์ด ๋‹ต์ž„์ด ์ž˜ ์•Œ๋ ค์ ธ ์žˆ๋‹ค.

Full solution

์œ„ DP๋ฅผ ๊ฐœ์„ ํ•˜๊ณ ์ž ํ•œ๋‹ค. ์ด๋•Œ, dp(i, x) ๋ฅผ $x$์— ๋Œ€ํ•œ ํ•จ์ˆ˜ $f_i (x)$์ฒ˜๋Ÿผ ์ƒ๊ฐํ•˜์ž. ๊ทธ๋ฆฌ๊ณ  ์ฒซ๋ฒˆ์งธ min ํŒŒํŠธ์™€, ๋‘๋ฒˆ์งธ abs๋ฅผ ๋”ํ•˜๋Š” ํŒŒํŠธ๋ฅผ ๋‚˜๋ˆ„๋ ค๊ณ  ํ•œ๋‹ค.

  • min์„ ํ•˜๋Š” ํŒŒํŠธ๋Š”, ํ•จ์ˆ˜์—์„œ ์ƒ๊ฐํ•˜๋ฉด, $f_i(x)$์˜ ๊ฐ’์„ ๊ทธ ์ฃผ๋ณ€ $H$๋งŒํผ์˜ ๊ตฌ๊ฐ„์˜ ์ตœ์†Œ๊ฐ’์œผ๋กœ ๋Œ€์ฒดํ•˜๋Š” ์—ฐ์‚ฐ์ด๋‹ค.
  • abs๋Š” ๊ทธ๋Œ€๋กœ, $f_i$์— ์ง์ ‘ $\abs{a_i - x}$ ๊ฐ€ ๋”ํ•ด์ง€๋Š” ์—ฐ์‚ฐ์ด๋‹ค.

๊ฒฐ๊ตญ ์ด ๋‘ ์—ฐ์‚ฐ์„ ๊ต๋Œ€๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ, $\abs{a - x}$ ํ•จ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ๋”ํ•ด์ง€๊ณ , ๊ตฌ๊ฐ„ minimum์„ ๊ณ„์† ์ทจํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋•Œ, abs ํ•จ์ˆ˜์˜ ํ•ฉ์ด ํ•ญ์ƒ convexํ•จ์— ์ฃผ๋ชฉํ•˜์ž. ๋˜ํ•œ, ํ•จ์ˆ˜์—์„œ ๊ธฐ์šธ๊ธฐ๊ฐ€ ๋ฐ”๋€Œ๋Š” ์ง€์ ์ด $2n$๊ฐœ ๋ฐ–์— ์—†์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

abs๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ๋”ํ•ด์ง„ ํ•จ์ˆ˜์— ๊ตฌ๊ฐ„ minimum์„ ์ทจํ•˜๋Š” ๊ฒƒ์€, ํ•จ์ˆ˜์˜ ๊ธฐ์šธ๊ธฐ ๋ถ€ํ˜ธ๊ฐ€ ๋ฐ”๋€Œ๋Š” ๋ถ€๋ถ„์„ ๊ธฐ์ค€์œผ๋กœ, ์–‘์ชฝ์˜ ๊ธฐ์šธ๊ธฐ๊ฐ€ ๋ฐ”๋€Œ๋Š” ์  ์„ ์™ผ์ชฝ ์ ์€ ๋” ์™ผ์ชฝ์œผ๋กœ, ์˜ค๋ฅธ์ชฝ ์ ์€ ๋” ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๋ฏธ๋Š” ํšจ๊ณผ๊ฐ€ ๋œ๋‹ค.

picture 1

์‚ฌ์ง„์€ ๊ณต์‹ ํ’€์ด์—์„œ ๊ฐ€์ ธ์™”๋‹ค. ์ด๊ฑธ ๊ทธ๋ฆด ์ž์‹ ์ด ์—†์–ด์„œโ€ฆ :(

๋”ฐ๋ผ์„œ, ์ ์ ˆํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์ด์šฉํ•˜์—ฌ, ํ•จ์ˆ˜์˜ ๊ธฐ์šธ๊ธฐ๊ฐ€ ๋ฐ”๋€Œ๋Š” ์ ๋“ค์„ ๋ชจ๋‘ ๊ธฐ๋กํ•˜๊ณ , ์ด๋“ค์„ ๋ฏธ๋Š” ์—ฐ์‚ฐ๊ณผ ์ถ”๊ฐ€ํ•˜๋Š” ์—ฐ์‚ฐ์„ ์ž˜ ํ•ด์ค„ ์ˆ˜ ์žˆ์œผ๋ฉด ๋œ๋‹ค.

๊ตฌํ˜„

์‚ฌ์‹ค ์ฒ˜์Œ์—๋Š” ์ €๊ธฐ๋‹ค๊ฐ€ Dynamic Lazy Segment Tree ๊ฐ™์€๊ฑธ ์ž˜ ๋ฐ•์•„์„œ ์–ด๋–ป๊ฒŒ ํ•ด๋ณด๋ ค๊ณ  ์ƒ๊ฐํ–ˆ์—ˆ๋Š”๋ฐ, ๋ช‡์‹œ๊ฐ„๋™์•ˆ ๊ณ ์ƒํ•˜๋‹ค๊ฐ€ ๊ฒฐ๊ตญ ์‹คํŒจํ–ˆ๋‹ค. ๊ณต์‹ ์†”๋ฃจ์…˜์€ (๊ทธ๋ฆฌ๊ณ  ๋‚ด๊ฐ€ ๋ณธ ๊ฑฐ์˜ ๋ชจ๋“  ํ’€์ด๋Š”) ์•„๋ž˜ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค.

๊ธฐ์šธ๊ธฐ๊ฐ€ ๋ฐ”๋€Œ๋Š” ์ ๋“ค์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ž. ๊ตฌํ˜„์˜ ํŽธ์˜๋ฅผ ์œ„ํ•ด, ์ด ๋ฆฌ์ŠคํŠธ๋Š” ๋ฐ˜๋ณต์„ ํ—ˆ์šฉํ•œ๋‹ค. ์ฆ‰, $(-\infty, 1)$ ์—์„œ์˜ ๊ธฐ์šธ๊ธฐ๊ฐ€ -3์ด๊ณ , $(1, 3)$ ์—์„œ์˜ ๊ธฐ์šธ๊ธฐ๊ฐ€ -1, $(3, 5)$์—์„œ์˜ ๊ธฐ์šธ๊ธฐ๊ฐ€ 0, $(5, 8)$์—์„œ์˜ ๊ธฐ์šธ๊ธฐ๊ฐ€ 1์ด๋ผ๋ฉด, ์ด๋ฅผ ์ €์žฅํ•  ๋•Œ 1, 1, 3, 5, 8 ๊ณผ ๊ฐ™์ด ์ €์žฅํ•œ๋‹ค. 1์ด ๋‘ ๋ฒˆ ๋‚˜์˜ค๋Š” ๊ฒƒ์€ ๊ธฐ์šธ๊ธฐ๊ฐ€ ๋‘ ๋ฒˆ ๋ณ€ํ•จ์„ ์ง์ ‘ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ํ•ด๋„, ์–‘์ชฝ์˜ ๊ธฐ์šธ๊ธฐ๊ฐ€ $-n$๋ถ€ํ„ฐ $n$๊นŒ์ง€์ด๊ธฐ ๋•Œ๋ฌธ์—, $2n$๊ฐœ ์ •๋„์˜ ์ ๋งŒ ์žˆ์œผ๋ฉด ๋œ๋‹ค.

์ด๋•Œ, ๊ธฐ์šธ๊ธฐ $0$์„ ๊ธฐ์ค€์œผ๋กœ, ์–‘์ชฝ์„ multiset ๊ฐ™์€ ์ž๋ฃŒ๊ตฌ์กฐ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค. ๋‚˜์ค‘์— ์ด ์ ๋“ค ์ „์ฒด๋ฅผ ๋“ค๊ณ  ์–‘์ชฝ์œผ๋กœ ๋ฐ€์–ด์•ผ ํ•˜๋Š”๋ฐ, ์ง์ ‘ ๋ฏธ๋Š” ๋Œ€์‹  offset์„ ๊ธฐ๋กํ•  ๊ฒƒ์ด๋‹ค.

  • min์—ฐ์‚ฐ์€ ์ด์ œ offset์„ ๋ฐ”๊ฟ”์คŒ์œผ๋กœ์จ $O(1)$์— ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • abs ๋ฅผ ๋”ํ•˜๋Š” ์—ฐ์‚ฐ์€, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜ํ–‰ํ•œ๋‹ค. ๋จผ์ € $\abs{a_i - x}$๋ฅผ ๋”ํ•˜๋ฉด $a_i$๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์™ผ์ชฝ์—๋Š” ๊ธฐ์šธ๊ธฐ๊ฐ€ -1 ๋”ํ•ด์ง€๊ณ , ์˜ค๋ฅธ์ชฝ์—๋Š” ๊ธฐ์šธ๊ธฐ๊ฐ€ 1 ๋”ํ•ด์ง„๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊ด€์ฐฐํ•˜์ž. ๋”ฐ๋ผ์„œ, $a_i$๋ฅผ ๋‘ ๋ฒˆ ๋„ฃ์–ด ์ฃผ๋ฉด, ์•„๋ฌด ๋ฌธ์ œ๊ฐ€ ์—†๊ฒŒ ๋œ๋‹ค.
    • ์ด๋•Œ, ์•ž์„œ ์–‘์ชฝ์„ multiset์œผ๋กœ ๊ฐ๊ฐ ๊ด€๋ฆฌํ•˜๊ธฐ๋กœ ํ–ˆ์œผ๋ฏ€๋กœ, $a_i$์˜ ์œ„์น˜๋ฅผ ๋ณด๊ณ  ์–ด๋””์— ๋„ฃ์–ด ์ฃผ์–ด์•ผ ํ•˜๋Š”์ง€ ์ฐพ์•„์•ผ ํ•œ๋‹ค.
    • ๋งŒ์•ฝ ์™ผ์ชฝ multiset์— ๋“ค์–ด๊ฐ€๋Š” ๊ฒฝ์šฐ, ์™ผ์ชฝ multiset์˜ ๋งจ ๋ ๊ฐ’ (๊ธฐ์šธ๊ธฐ๊ฐ€ ์›๋ž˜ -1์—์„œ 0์œผ๋กœ ๋„˜์–ด๊ฐ€๋Š” ๋ถ€๋ถ„)์ด ์ด์ œ 0์—์„œ 1๋กœ ๋„˜์–ด๊ฐ€๋Š” ๋ถ€๋ถ„์ด ๋œ๋‹ค. ๋”ฐ๋ผ์„œ, ์ด๋ฅผ ์™ผ์ชฝ์—์„œ ๋นผ์„œ ์˜ค๋ฅธ์ชฝ์— ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ๊ทธ ๋ฐ˜๋Œ€์ด๋ฉด ๋‹น์—ฐํžˆ ๊ฐ’์˜ ๋ฐฉํ–ฅ์ด ๋ฐ˜๋Œ€๋กœ ๊ฐ„๋‹ค.
  • ๋งˆ์ง€๋ง‰์— ๊ธฐ์šธ๊ธฐ 0์— ํ•ด๋‹นํ•˜๋Š” $x$๋ฅผ ๋ณด๊ณ  ๋‹ตํ•˜๋ฉด ๋œ๋‹ค. ํ•จ์ˆ˜๊ฐ’์˜ ์‹ค์ œ ๊ณ„์‚ฐ๋„ ๋ณ„๋กœ ์–ด๋ ต์ง€ ์•Š๋‹ค.
    ๋ง๋กœ ์„ค๋ช…ํ•˜๊ธฐ ์ •๋ง ๋”์ฐํ•˜์ง€๋งŒ, ์ฝ”๋“œ๋Š” ๊ทธ๋ ‡๊ฒŒ ์‹ฌ๊ฐํ•˜๊ฒŒ ์–ด๋ ต์ง€ ์•Š๋‹ค. ์ด๊ฑธ ๊ธฐ์šธ๊ธฐ๊ฐ’์„ ๊ทธ๋Œ€๋กœ multiset๊ฐ™์€๊ฑธ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค๋Š” ๋ฐœ์ƒ์ด ๊ฐ€์žฅ ์–ด๋ ค์šด ๊ฒƒ ๊ฐ™๋‹ค.

์ฝ”๋“œ

#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#define ll long long
#define eps 1e-7
#define all(x) ((x).begin()),((x).end())
#define usecppio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
#define int ll
using pii = pair<int, int>;
int INF = 1e15;
const int MN = 202020;
const int LEND = -1e17;
const int REND = 1e17;
int N, H;
int s[MN];

struct mset {
    multiset<int> st;
    int offset;
    int small() {
        return *st.begin() + offset;
    }
    int large() {
        return *st.rbegin() + offset;
    }
    void del(int e) {
        if (e == LEND)
            st.erase(st.begin());
        else if (e == REND)
            st.erase(prev(st.end()));
        else
            st.erase(st.lower_bound(e));
    }
    void ins(int e){
        st.insert(e);
    }
} l, r;

int32_t main()
{
    usecppio
    cin >> N >> H;
    int MH = 0;
    for (int i = 1; i <= N; i++)
    {
        cin >> s[i];
        MH = max(MH, s[i]);
    }
    l.ins(s[1]);
    r.ins(s[1]);
    int ans = 0;
    for (int i = 2; i <= N; i++)
    {
        l.offset -= H;
        r.offset += H;
        int lf = l.large();
        int rf = r.small();
        if (s[i] < lf)
        {
            l.ins(s[i] - l.offset);
            l.ins(s[i] - l.offset);
            l.del(REND);
            r.ins(lf - r.offset);
            ans += abs(lf - s[i]);
        }
        else if (s[i] > rf)
        {
            r.ins(s[i] - r.offset);
            r.ins(s[i] - r.offset);
            r.del(LEND);
            l.ins(rf - l.offset);
            ans += abs(rf - s[i]);
        }
        else
        {
            l.ins(s[i] - l.offset);
            r.ins(s[i] - r.offset);
        }
    }
    cout << ans << '\n';
}