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

이번 문제는 스케이트 코스에서 각 중간 지점의 속도 제한을 고려하여, 스케이터가 이동해야 하는 경로의 속도 합을 최대화하는 문제입니다. 효율적인 속도 할당을 통해 전체 이동 거리의 합을 최대화하면서도 주어진 속도 제한과 속도 조절 규칙을 준수해야 합니다.
0에서 출발.V_i가 있음.0이 될 수 없음 (출발 및 도착 지점을 제외).0으로 도착.N (1 ≤ N ≤ 500,000)과 도착 지점 번호 M (3 ≤ M ≤ 10^9).N줄: 각 중간 지점의 속도 제한 V_i (1 ≤ V_i ≤ 1,000,000,000).예제 입력 1:
3
2 3 1
예제 출력 1:
5
해석:
예제 입력 2:
4
23 7 1 5
예제 출력 2:
7
해석:
스케이터의 속도를 최대화하기 위해 뒤에서부터 앞으로 속도를 할당하는 그리디 알고리즘을 사용합니다. 이를 통해 각 중간 지점에서 가능한 최대 속도를 결정하면서도, 속도를 낮출 때의 제한 사항을 만족시킬 수 있습니다.
1이어야 합니다.1만큼 높을 수 있습니다.V_i를 초과할 수 없으며, 다음 지점의 속도보다 최대 1만큼 높을 수 있습니다.speed[N] = min(V[N], 1) (도착 지점으로 가기 위해 최소 1).i = N-1부터 1까지:speed[i] = min(V[i], speed[i+1] + 1)N과 M을 입력받습니다.V_i를 리스트에 저장합니다.min(V[N-1], 1)로 설정합니다.i = N-2부터 0까지 반복하며:speed[i] = min(V[i], speed[i+1] + 1)예제 입력 1:
3
2 3 1
속도 할당 과정:
speed[2] = min(1, 1) = 1speed[1] = min(3, 1 + 1) = 2speed[0] = min(2, 2 + 1) = 2예제 입력 2:
4
23 7 1 5
속도 할당 과정:
speed[3] = min(5, 1) = 1speed[2] = min(1, 1 + 1) = 1speed[1] = min(7, 1 + 1) = 2speed[0] = min(23, 2 + 1) = 3아래는 위의 접근 방식을 바탕으로 작성한 파이썬 코드입니다. 효율적인 입력 처리를 위해 sys.stdin을 사용하였으며, 시간 및 공간 복잡도를 고려하여 최적화하였습니다.
import sys
def solution():
import sys
def input():
return sys.stdin.read()
data = input().split()
idx = 0
N = int(data[idx])
idx +=1
V = list(map(int, data[idx:idx+N]))
idx +=N
total =0
# Initialize the speed at the last intermediate point
current_speed = min(V[-1], 1)
total += current_speed
# Iterate from second last to first
for i in range(N-2, -1, -1):
# The maximum speed at this point is min(V[i], current_speed +1)
current_speed = min(V[i], current_speed +1)
total += current_speed
print(total)
if __name__ == "__main__":
solution()
import sys
def solution():
import sys
def input():
return sys.stdin.read()
data = input().split()
idx = 0
N = int(data[idx])
idx +=1
V = list(map(int, data[idx:idx+N]))
idx +=N
sys.stdin.read():N이 최대 500,000까지 커질 수 있으므로, 빠른 입력 처리가 중요합니다.data 리스트:idx를 사용하여 현재 읽고 있는 위치를 추적합니다.V 리스트:V[0]부터 V[N-1]까지 저장됩니다. total =0
# Initialize the speed at the last intermediate point
current_speed = min(V[-1], 1)
total += current_speed
# Iterate from second last to first
for i in range(N-2, -1, -1):
# The maximum speed at this point is min(V[i], current_speed +1)
current_speed = min(V[i], current_speed +1)
total += current_speed
current_speed:speed[i] = min(V[i], speed[i+1] + 1)1만큼만 높일 수 있음을 의미합니다.total에 더합니다. print(total)
O(N) 시간 복잡도.N개의 속도 제한을 읽어들이고, 리스트에 저장합니다.O(N) 시간 복잡도.전체 시간 복잡도: O(N)
N이 최대 500,000이므로, 이 알고리즘은 매우 효율적이며 제한 시간 내에 충분히 동작합니다.O(N) 공간 복잡도.V가 필요합니다.O(1) 공간 복잡도.total과 current_speed 변수만을 사용합니다.전체 공간 복잡도: O(N)
N이 최대 500,000으로, 이는 파이썬 리스트에 충분히 저장 가능합니다.1이어야 하므로, 이 지점부터 시작하여 앞쪽 지점의 속도를 결정합니다.1 이하로 유지합니다.speed[i] = min(V[i], speed[i+1] + 1)1만큼만 높일 수 있음을 보장합니다.V 리스트:total: 전체 속도 합을 저장하는 변수로, 간단한 누적 합산을 위해 사용됩니다.current_speed: 현재 할당할 속도를 추적하는 변수로, 속도 할당 규칙을 적용하는 데 사용됩니다.