umineko-sephi’s blog

いろいろ書きます

CODE FESTIVAL 2014 Middle D - ぽよぽよ

最近のAtCoder Problemsのアップデートで昔の問題がお勧めに出てくるようになりました。誰も解説書いてなかったので(多分)書きます。

 

atcoder.jp

 

問題

直線状にn匹のぽよくんが存在している。i番目のぽよくんはp_i-l_iからp_i+l_iの範囲のマスを自由に移動できる。ぽよくんが添え字の順にそれぞれ異なるマスにいるとき何通りの配置があるかを1000000007で割った値を求めよ。

 

制約

1\le n\le1,000

0\le p_i\le1,000,000,000

0\le l_i\le1,000

i\lt jのときp_i\lt p_j

 

解説

まずわかりやすくするためにp_i = p_i - l_iとして移動できる区間の左端にそろえておく。また、一番初めの要素としてp_0 = -INF, l_0 = 0などを入れておくと処理が簡単になる。

{dp_i} _j := i番目のぽよをマスp_i + jに配置したときの通り数

としてdpを行う。このままdpを行うと遷移のパターンが{l_i} {_+} _1  * 2 +1通りあるため制限時間に収めることができない。しかし、マスp_i + jにぽよを配置できるときマスp_i + j + 1にもぽよを配置しても問題ないことがわかる。よって配置可能な左端のマスを持ってそこに足していき、累積和の要領でそれ以降のマス目に足せばよい。

時間計算量はO(n*l)

 

自分の提出

atcoder.jp