Official
E - 山道のハイキングコース / Hiking Course on a Mountain Trail Editorial
by
E - 山道のハイキングコース / Hiking Course on a Mountain Trail Editorial
by
sounansya
Editorial for printing
\(i+H_i'\) の偶奇は必ず一致する必要があります。
\(i+H_i'\) が全て偶数であるような場合を考えます。
\(\lbrace 1,2,\ldots,N\rbrace\) の部分集合 \(S\) に対し、\(i\in S\) ならば \(H_i=H_i'\) という条件を考えます。この条件を満たす \(S\) に対する \(|S|\) の最大値が問題の答えです。また、この条件は \(i,j\in S\) に対し \(|H_i - H_j| \le |i-j| \) が成り立つことと同値です。
さらに、\(X_i=H_i-i,Y_i=H_i+i\) とすると、\(i,j\in S\) に対し \(X_i < X_j\) ならば \(Y_i \le Y_j\) 、となります。これは \((X_i,Y_i)\) を辞書順にソートした際の \(Y_i\) の広義単調増加列の長さと一致します。広義単調増加列は準線形時間で計算できるため、ソートを含めても準線形時間で問題の答えを求めることができます。
全て奇数である場合も同様に計算することができます。
以上を適切に実装することでこの問題に正答することができます。
from bisect import bisect_right
def lis(a):
d = []
for v in a:
i = bisect_right(d, v)
if i == len(d):
d.append(v)
else:
d[i] = v
return len(d)
n = int(input())
h = list(map(int, input().split()))
a = []
b = []
for i, x in enumerate(h):
p = (i - x, i + x)
if (i + x) % 2:
a.append(p)
else:
b.append(p)
def calc(arr):
arr.sort()
e = [x for _, x in arr]
return lis(e)
print(max(calc(a), calc(b)))
posted:
last update:
