https://www.acmicpc.net/problem/2419
2419번: 사수아탕
첫째 줄에 n과 m이 주어진다. 둘째 줄부터 n개의 줄에 사탕 바구니의 위치 xi가 주어진다. (0 ≤ n ≤ 300, 1 ≤ m ≤ 1,000,000, -10,000 ≤ xi ≤ 10,000) 사탕 바구니의 위치는 중복되지 않는다.
www.acmicpc.net
상당히 유명한 문제이다. 인터넷을 찾아보니 다른 분들과 조금은 다른 접근을 한 것 같아 풀이를 적어본다.
우선 보자마자 드는 생각은 dp를 해야할 것 같다는 것과, dp(l,r,k) = [l,r]까지 사탕을 먹었고, k=0이면 l, 1 이면 r에 있을 때 정답 정도로 정의해서 계산하면 될 것 같았다. 하지만 이 방법은 다음 사탕을 먹을 때 몇개나 먹을 수 있을지 알 수 없기에, dp(l,r,k,t), t는 현재 시간. 이 필요할 것 같았다. 하지만 이 식은 t가 최대 백만이기에 너무 느리다.
문제를 조금 바꿔보자. 구간 [l,r]을 전부 순회했을 때, 각 지점을 방문하는 시간을 방문한 순서대로 T1,T2,⋯,Tr−l+1이라 하자. 이때 이 구간에서 먹는 사탕의 개수는 m(r−l+1)−∑Ti 가 될 것이다. 즉, 구간에서 ∑Ti 를 최소화하는 문제와 동일하다.
그럼 이때 각 Ti는 어떠한 값들일까? 구간에서 i번째로 방문한 지점을 Pi라 하면, Ti=∑i−1j=1Tj+dist(Pi−1,Pi) 가 될 것이다. 이제 이 식을 풀면, 최종적으로 N개의 지점들을 방문한다 할 때에, ∑Ni=1Ti=∑N−1i=1(N−i+1)⋅dist(Pi,Pi+1) 가 될 것이다. 이때 부분 최적 구조를 만들기 위해 방문하는 지점 N개를 고정한다 해보자. 그럼 각 지점들간의 거리에 곱해지는 값을 쉽게 알 수 있기에, dp(l,r,k) = [l,r]을 순회했고 k=0이면 l에, 1이면 r에 있을 때 ∑Ti 의 최솟값 에 대한 문제는 간단한 dp로 계산할 수 있다. 이때 항상 0에서 출발해야하기에, dp값을 거꾸로 계산해준다는 느낌으로 하면 된다. 최종 시간 복잡도는 O(N3) 이 된다.
'알고리즘' 카테고리의 다른 글
AtCoder Beginner Contest 330 - 민트를 가다 (2) | 2023.11.25 |
---|---|
AtCoder Beginner Contest 327 (1) | 2023.11.04 |
신나는 추석 기념 oi 돌기 1편 (NOI singapore 2023) (0) | 2023.09.28 |
ps 일기 (NYPC 1519 본선 진출!) (0) | 2023.08.26 |
코드포스 블루 달성 + 정올 얘기 + 잡설 (1) | 2023.07.27 |