codeiq @riverplus さんの「プラス・マイナス・ゼロ問題」を解いた。

問題&解法はこちら。
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

コメントを残す