結果
| 問題 | No.3513 Greedy Yokan Party |
| コンテスト | |
| ユーザー |
yt142857
|
| 提出日時 | 2026-04-14 22:58:05 |
| 言語 | PyPy3 (7.3.17) |
| 結果 |
AC
|
| 実行時間 | 561 ms / 2,000 ms |
| コード長 | 1,824 bytes |
| 記録 | |
| コンパイル時間 | 198 ms |
| コンパイル使用メモリ | 84,864 KB |
| 実行使用メモリ | 133,348 KB |
| 最終ジャッジ日時 | 2026-04-24 20:51:36 |
| 合計ジャッジ時間 | 9,851 ms |
|
ジャッジサーバーID (参考情報) |
judge3_1 / judge2_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 26 |
ソースコード
import sys
def solve():
input = sys.stdin.readline
N, L = map(int, input().split())
K = int(input())
A = list(map(int, input().split()))
# 切れ目によって区切られる各区間の長さ
d = [A[0]]
for i in range(1, N):
d.append(A[i] - A[i - 1])
d.append(L - A[-1])
M = N + 1
limit = M - K + 1 # 2つの大きい部分列が使ってよい区間数の上限
def feasible(H: int) -> bool:
if H <= 0:
return True
INF = 10**18
# pref[i] = d[0..i] の中で、和 >= H となる部分列の最小長
pref = [INF] * M
s = 0
l = 0
best = INF
for r in range(M):
s += d[r]
while s >= H:
best = min(best, r - l + 1)
s -= d[l]
l += 1
if r > 0:
pref[r] = min(pref[r - 1], best)
else:
pref[r] = best
# suf[i] = d[i..M-1] の中で、和 >= H となる部分列の最小長
suf = [INF] * M
s = 0
r = M - 1
best = INF
for l in range(M - 1, -1, -1):
s += d[l]
while s >= H:
best = min(best, r - l + 1)
s -= d[r]
r -= 1
if l < M - 1:
suf[l] = min(suf[l + 1], best)
else:
suf[l] = best
# 左側の部分列と右側の部分列を分けて選ぶ
for i in range(M - 1):
if pref[i] + suf[i + 1] <= limit:
return True
return False
lo, hi = 0, L + 1
while hi - lo > 1:
mid = (lo + hi) // 2
if feasible(mid):
lo = mid
else:
hi = mid
print(lo)
if __name__ == "__main__":
solve()
yt142857