結果
| 問題 | No.3368 トッピング |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-06-14 21:11:26 |
| 言語 | PyPy3 (7.3.17) |
| 結果 |
AC
|
| 実行時間 | 1,476 ms / 2,000 ms |
| コード長 | 3,397 bytes |
| 記録 | |
| コンパイル時間 | 264 ms |
| コンパイル使用メモリ | 85,376 KB |
| 実行使用メモリ | 150,656 KB |
| 最終ジャッジ日時 | 2026-06-14 21:11:47 |
| 合計ジャッジ時間 | 10,813 ms |
|
ジャッジサーバーID (参考情報) |
judge1_1 / judge2_1 |
| 純コード判定待ち |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 14 |
ソースコード
## https://yukicoder.me/problems/no/3368
from collections import deque
MAX_INT = 10 ** 18
MIN_INT = - 10 ** 18
def solve(N, M, C, X, A, min_value):
# 洗濯できる食べ物の種類を位置ごとに選定
enables = []
for i in range(N):
row = []
for j in range(M):
if A[i][j] >= min_value:
row.append(j)
enables.append(row)
# keyは state , j * 2 + [すでに隣接するアイテムがあるかないかフラグ]
def calc_best_3(dp):
best_3 = [MAX_INT] * (3 * 2)
for state, x_value in dp.items():
for k in range(3):
if best_3[2 * k] > x_value:
for k_ in reversed(range(k, 2)):
for l in range(2):
best_3[2 * (k_ + 1) + l] = best_3[2 * k_ + l]
best_3[2 * k] = x_value
best_3[2 * k + 1] = state
break
return best_3
row = enables[0]
dp = {j * 2 :1 for j in row}
best_3 =calc_best_3(dp)
for i in range(1, N):
new_dp = {}
for j in enables[i]:
# 異なる食べ物の種類からの遷移
for k in range(3):
x_value = best_3[2 * k]
state = best_3[2 * k + 1]
prev_j = state // 2
has_same_near = state % 2
if best_3[2 * k + 1] == MIN_INT:
break
if prev_j != j:
new_x_value = x_value + 1
new_state = 2 * j
else:
continue
if new_state not in new_dp:
new_dp[new_state] = MAX_INT
new_dp[new_state] = min(new_dp[new_state], new_x_value)
# 同じ食べ物の種類を並べる
target_prev_state = 2 * j + 1
if target_prev_state in dp and A[i][j] - C >= min_value:
new_x_value = dp[target_prev_state]
new_state = 2 * j + 1
if new_state not in new_dp:
new_dp[new_state] = MAX_INT
new_dp[new_state] = min(new_dp[new_state], new_x_value)
target_prev_state = 2 * j
if target_prev_state in dp and A[i][j] - C >= min_value and A[i - 1][j] - C >= min_value:
new_x_value = dp[target_prev_state] - 1
new_state = 2 * j + 1
if new_state not in new_dp:
new_dp[new_state] = MAX_INT
new_dp[new_state] = min(new_dp[new_state], new_x_value)
dp = new_dp
best_3 = calc_best_3(dp)
for value in dp.values():
if 0 <= value <= N - X:
return True
return False
def main():
N, M, C, X = map(int, input().split())
A= []
for _ in range(N):
A.append(list(map(int, input().split())))
max_a = -float("inf")
min_a = float("inf")
for row in A:
max_a = max(max_a, max(row))
min_a = min(min_a, min(row) - C)
low = min_a
high = max_a
while high - low > 1:
mid = (high + low) // 2
if solve(N, M, C, X, A, mid):
low = mid
else:
high = mid
if solve(N, M, C, X, A, high):
print(high)
else:
print(low)
if __name__ == '__main__':
main()