天下一プログラマーコンテスト D - Three Colors
S=∑iaiとせよ。Rの和がS/2以上だと三角形は作れないし、G、Bについても同様である。三角形を作れないような塗り方の総数は(Rの和がS/2以上になるような塗り方)+(Gの和がS/2以上になるような塗り方)+(Bの和がS/2以上になるような塗り方)でだいたい求まるので、それを3Nから引けば答えになる。「だいたい」というのは、Sが偶数の時は色Xの和がS/2かつ色Yの和がS/2であるような塗り方が存在するかもしれないので、上の式だと重複して数えてしまうことになるからである。
とりあえずSが奇数の場合を考える。数列をa1,...,axに限定した時にRの和がuになるような塗り方の総数をf(x,u)とすると、
f(x,u)=f(x−1,u−ax)+2f(x−1,u)
である。G、Bについても同じ数になるので、答えは
3N−3u=⌈S/2⌉∑Sf(N,u)
であり、DPすれば良い。
Sが偶数の場合、重複して数えた分を引かなければならない。数列a1,...,axをX、Yの2色に塗り分けるとして、色Xの和がuになるような塗り方の総数をg(x,u)とすると、
g(x,u)=g(x−1,u−ax)+g(x−1,u)
が成り立つ。上の式では、Rの和がS/2かつGの和がS/2、Gの和がS/2かつBの和がS/2、Bの和がS/2かつRの和がS/2という3つのパターンを2回数えているので、重複の総数は3g(N,S/2)である。したがって、Sが偶数の場合の答えは
3N−(3u=S/2∑Sf(N,u)−3g(N,S/2))
になる。計算量はO(N2maxiai)。
考察の序盤は、まず数列a1,...,axの塗り分けでRの和がu、Gの和がvになるようなものの総数をf(x,u,v)として考えていた。しかし、これではもちろん間に合わないしデータ構造による高速化も思いつけず、なんとかf(x,u)だけで済まないだろうかと悩んだ末に上の方針に思いいたった。補集合に注目するのが習慣化していればもう少し早く正解にたどり着けたかもしれない。