怠惰の累積和

技術/競プロ/怪文書/虚無

技術室奥プログラミングコンテスト#4 Day1 D - スキップ

問題概要

 N個のマス目があり、i(1≦i≦N)個目のマス目にはA_iが書かれている。この内、任意の個数のマス目を選んだ時、選んだマス目の集合V={V_1,V_2,...}について、|V_2-V_1|+|V_3-V_2|...点分のポイントが得られる時、ポイントの最大値を達成するVの要素数の最小値を求める。

atcoder.jp

 

解法

 A_iのある連続した3要素について考えてみる(下では1,3,5としている)。

f:id:severrabaen:20190802102724p:plain

 ここで、5を飛ばして1から3まで行ったとしても(赤の経路)、両者の差の絶対値は2のため、2ポイントしか得られないため、この時点で最大値を達成することは不可能となってしまう。このような場合は素直に5を飛ばさないで|5-1|+|3-5|=6ポイントを得た方が良い。

 反対に、これが1,3,5のような並びであった場合、3を飛ばしても得られるポイントは最終的に同じ6ポイントである。

 このことから、連続する要素の内、(左端がその要素の集合中の最小値∧右端が最大値)∨(左端がその要素の集合中の最大値∧右端が最小値)が成り立っていれば両端の2要素以外は全てスキップすることができる。

 よって、各i(1≦i≦N)について、その直前までのAが増加であったか若しくは減少であったかを見てあげて、直前までは増加しているのにA_iでは減少している、もしくはその逆であれば答えに1を足していけばよい。

 ただ、多分これが想定コーナーケースだろうと勝手に思っているが、Aの全要素が同じ場合、どんな選び方をしてもポイントは0になるため、問題文曰く、遊ばないという選択を取って0を答えとしなければならない。

 これを実装して、AC。O(N)

atcoder.jp