問題&解法はこちら。
https://codeiq.jp/magazine/2016/02/37963/
問題は、大体下記のような感じ。
自然数 n に対して、次の等式を考えます。
□1□2□3□4…□n = 0
四角の部分には、プラス(+)またはマイナス(-)の記号が入ります。
自然数 n に対し、等式を成立させる記号の入れ方の数を F(n) と定義します。
標準入力から、自然数 n(1 ≦ n ≦ 50)が与えられます。
標準出力に F(n) の値を出力するプログラムを書いてください。
提出コードはruby。(コメントだけ追加しました。)
基本的には、ひとつひとつ+-していったときの値を、まとめて勘定しているだけ。
一番最初に全通り数え上げてみるのを書いてみた後、それではとてもとても無理ということで書き直した感じ。
def solve(n)
# 1..j の数字について処理した結果の値をキーに、そのキーの値になる
# +-の組み合わせの数を値として持つ連想配列を考える。
# (Arrayだとインデックスが負にならないような小細工が必要で面倒)
ret = {1 => 1} # -1から始まるものは、対称性から最後に2倍してすます
(2..n).each{|j|
tmp = Hash.new{|h,k| h[k] = 0}
# j番目のHashは、j-1 番目のHashの各要素{k=>v}について、
# k+j, k-j の値にvを足していくことで得られる。
ret.each{|k,v|
tmp[k+j] += v
tmp[k-j] += v
}
ret = tmp
}
ret[0] * 2
end
while str = STDIN.gets
n = str.chomp.to_i
puts solve(n)
end