CodeIQ 挑戦の記録 : 「プラス・マイナス・ゼロ」問題
CodeIQというサイトで問題に挑戦した記録です。
「プラス・マイナス・ゼロ」問題
問題文を要約すると、
自然数1からnまでを並べ、それぞれの前に「+」か「ー」を配置した式を考える時、
合計が0になる「+」と「ー」の並べ方が何通りあるか解答するもの。
方針
仮にa+b-c-d=0が成り立つとする
これを変形しa+b=c+dとする。
この場合、題意よりaからdは1から4までの数値であり、
aからdまでを全て加算した値は1から4までの公差1の等差数列の和に等しい。
ゆえに、この場合、a+bとc+dは1から4までの等差数列の和を2で割ったものに等しい。
これより、1からnまでの整数の中で、等差数列の和を2で割った値に等しくなる組み合わせの数を解答とする。
なお、等差数列の和の公式 において、この和の更に1/2と等しくなる組み合わせを求めるので、
が4で割り切れなければ題意を満たす自然数の組はない。
(nを4で割って余りが1か2であれば問題の等式はできないので0を解答とする)
実装
1からnまでの自然数の中で と等しくなる組み合わせを探す事になるが、幾つかの要素を組み合わせて最適なものを選んだ
パターン数を求めるという事では有名問題:ナップサック問題の変形と考えて良い。
*ナップサック問題の説明(動的計画法スライド・4ページから)
www.slideshare.net
動的計画法を用いる
1からiまでの数値の中で加算してjになる組み合わせのパターン数をとすると、
下記の通りの漸化式で表す事ができる。
下記の様にdpテーブルを作成し、縦軸(i)をnまでの数値、横軸(j)を加算した数値、テーブルの要素はパターン数とすると、
i番目の数値jはi-1番目の数値j-iにiを加えたものとi-1番目の数値をそのまま持ってきた2パターンの合計である。
以上を用いて実装し、提出したソースコードは下記(Ruby)
また、最初は下記のメモ化再帰で実装したが、ローカルで試した時に最大の入力値(48)で1秒の時間制限に間に合わなかった為、上記の動的計画法版で提出した。
(上記のものは余裕でクリアできた)
Sponsored Link