結果
問題 |
No.595 登山
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:26:52 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 139 ms / 1,500 ms |
コード長 | 2,959 bytes |
コンパイル時間 | 265 ms |
コンパイル使用メモリ | 82,360 KB |
実行使用メモリ | 112,512 KB |
最終ジャッジ日時 | 2025-05-14 13:27:40 |
合計ジャッジ時間 | 4,255 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 25 |
ソースコード
import sys def solve(): N, P = map(int, sys.stdin.readline().split()) H = list(map(int, sys.stdin.readline().split())) if N == 1: print(0) return # D_fwd[m] = cost to move from H[m] to H[m+1] D_fwd = [0] * (N - 1) for m in range(N - 1): D_fwd[m] = max(0, H[m+1] - H[m]) # PD_fwd[x] = sum of D_fwd[0]...D_fwd[x-1] # PD_fwd[k] = cost to walk H[0] -> H[1] -> ... -> H[k] PD_fwd = [0] * N current_sum_fwd = 0 # PD_fwd[0] = 0 (cost to walk H[0] -> H[0]) for x in range(N - 1): current_sum_fwd += D_fwd[x] PD_fwd[x+1] = current_sum_fwd # D_rev[m] = cost to move from H[m+1] to H[m] D_rev = [0] * (N - 1) for m in range(N - 1): D_rev[m] = max(0, H[m] - H[m+1]) # PD_rev[k] = cost to walk H[k] -> H[k-1] -> ... -> H[0] PD_rev = [0] * N current_sum_rev = 0 # PD_rev[0] = 0 (cost H[0] -> H[0]) for x in range(N - 1): current_sum_rev += D_rev[x] # D_rev[x] is cost H[x+1] -> H[x] PD_rev[x+1] = current_sum_rev # dp[k] = min cost to cover H[0]...H[k-1] (first k locations) dp = [0] * (N + 1) # dp[0] to dp[N] dp[1] = 0 # Cost to cover H[0] (first location) is 0 as we start there. # min_term_fwd will store min(dp[x] - PD_fwd[x]) for x from 1 up to current k-1. # min_term_rev will store min(dp[x] - PD_rev[x]) for x from 1 up to current k-1. # Initialize with x=1 values. # PD_fwd[1] is cost H[0]->H[1]. # PD_rev[1] is cost H[1]->H[0]. min_term_fwd = dp[1] - PD_fwd[1] min_term_rev = dp[1] - PD_rev[1] for k in range(2, N + 1): # Option 1: Walk H[0] -> ... -> H[k-1] in one segment # Cost is sum D_fwd[0]...D_fwd[k-2], which is PD_fwd[k-1]. val_one_segment_fwd = PD_fwd[k-1] # Option 2a: Split. Last segment H[j_idx]...H[k-1] walked H[j_idx]->H[k-1]. # Here, j_idx is the 0-based index. dp[j] covers first j locations H[0]...H[j-1]. # New segment from H[j] to H[k-1]. # cost dp[j] + P + (PD_fwd[k-1] - PD_fwd[j]) # This is P + PD_fwd[k-1] + (dp[j] - PD_fwd[j]) # where j loops from 1 to k-1. min_term_fwd stores min(dp[j] - PD_fwd[j]) term_A = P + PD_fwd[k-1] + min_term_fwd # Option 2b: Split. Last segment H[j_idx]...H[k-1] walked H[k-1]->H[j_idx]. # cost dp[j] + P + (PD_rev[k-1] - PD_rev[j]) # This is P + PD_rev[k-1] + (dp[j] - PD_rev[j]) term_B = P + PD_rev[k-1] + min_term_rev dp[k] = min(val_one_segment_fwd, term_A, term_B) # Update min_terms for next iteration (for k+1, this k will be part of j range) # dp[k] refers to covering first k locations. PD_fwd[k] is cost H[0]...H[k]. if k < N : min_term_fwd = min(min_term_fwd, dp[k] - PD_fwd[k]) min_term_rev = min(min_term_rev, dp[k] - PD_rev[k]) print(dp[N]) solve()