geam1113’s diary

主にAtcoderのコンテストの備忘録を書きます。AtCoder緑と水色を行ったり来たりしています。

AtCoder Biginner Contest 262 参加記録

コンテストへのリンク:
コンテスト中AC:A〜D

D - I Hate Non-integer Number

数列の部分和に関する問題なので、部分和DPを考えます。

  • dp[i][j]:=数列Ai項目までの部分和であって、和がjとなるものの個数

今回は、何個選んだかも必要なので、情報を足します。

  • dp[i][j][k]:=数列Ai項目までの部分和であって、部分和を構成する要素の数がj個、その和がkであるものの個数

今回、数列の要素数N\leq 100と少ないですが、1\leq a_i \leq 10^9であり、和のとりうる範囲が非常に大きく、上記のDPは使えません。

ここで、選ぶ要素数を固定し、X個とします。
X個の要素からなる部分和Sの平均が整数となるためには、SXの倍数である必要があります。すなわち、以下の条件を満たせばよいです。
S\ mod\ X = 0

つまり、部分和のmod\ Xだけわかれば、倍数となるかを判定できます。
そこで、以下のDPが考えられます。

  • dp[i][j][k]:=数列Ai項目までの部分和であって、部分和を構成する要素の数がj個であり、その和をSとした時にS\ mod\ X = kであるものの個数

このようにすれば、kのとりうる範囲も0\leq k \leq N-1となり、N個に限定されます。

計算量は、DPテーブルを埋めるためにO(N^3)かかり、X=1,2,\cdots ,Nのそれぞれについて計算する必要があるので、O(N^4)だと思います。
実装はコンテスト後に見直ししたもの。
Submission #33697694 - AtCoder Beginner Contest 262