E - Bowls and Beans Editorial
by
tatyam
\(L_i := i - C_i\) と定義します.また,茶碗 \(0\) には豆が入っているものとします.
公式解説の考察より,以下の操作を繰り返せば良いです.
- 最も後ろにある豆の入った茶碗を茶碗 \(i\) とする.茶碗 \(i\) に入った豆を以下の茶碗に移動させる.
- 茶碗 \(L_i, L_i + 1, \dots, i-1\) の中に豆の入った茶碗があれば,そのうち最も後ろにあるものに豆を移動させる.
- 茶碗 \(L_i, L_i + 1, \dots, i-1\) の中に豆の入った茶碗がなければ,そのうち \(L\) が最も小さい茶碗に豆を移動させる.
これを実装することで \(O(N)\) 時間で解くことができます.
実装例 (Python)
N = int(input())
C = [0] + list(map(int, input().split()))
A = [1] + list(map(int, input().split()))
L = [i - C[i] for i in range(N)]
ans = 0
for i in range(N - 1, 0, -1):
# 最も後ろにある豆の入った茶碗を見つける
if A[i] == 0:
continue
# この豆を以下の場所に移動させる
ans += 1
l = L[i]
# 茶碗 [l:i] に豆の入った茶碗があれば,そのうち最も後ろの茶碗に移動
if any(A[j] for j in range(i - 1, l - 1, -1)):
continue
# なければ,茶碗 argmin(L[l:i]) に移動
mn = 1 << 60
argmn = -1
for j in range(i - 1, l - 1, -1):
if mn > L[j]:
mn = L[j]
argmn = j
A[argmn] = 1
print(ans)
posted:
last update: