「プログラマ脳を鍛える数学パズル」という本に載っている
「Q30 テーブルタップで作るタコ足配線」の解答コードが理解できません。
どなたかコードのアルゴリズムを解説していただけないでしょうか?
問題は以下です。
口数が2つと3つのテーブルタップを組み合わせてぴったりN個の空いている口を作る。
N=20の時、作れるパターン数を求めよ。
(ただし、同じテーブルタップに挿す場合、挿す場所によっての場合分けは考えない)
例としN=4の場合、下図のように4パターン作ることが出来る。
解答のコードは以下です
Ruby
1N = 20 2 3@memo = {1 => 1} 4def set_tap(remain) 5 return @memo[remain] if @memo.has_key?(remain) 6 cnt = 0 7 # 2口 8 (1..(remain / 2)).each{|i| 9 if remain - i == i then 10 cnt += set_tap(i) * (set_tap(i) + 1) / 2 11 else 12 cnt += set_tap(remain - i) * set_tap(i) 13 end 14 } 15 # 3口 16 (1..(remain / 3)).each{|i| 17 (i..((remain - i) / 2)).each{|j| 18 if (remain - (i + j) == i) && (i == j) then 19 cnt += set_tap(i) * (set_tap(i) + 1) * (set_tap(i) + 2) / 6 20 elsif remain - (i + j) == i then 21 cnt += set_tap(i) * (set_tap(i) + 1) * set_tap(j) / 2 22 elsif i == j then 23 cnt += set_tap(remain - (i+j)) * set_tap(i) * (set_tap(i)+1) / 2 24 elsif remain - (i + j) == j then 25 cnt += set_tap(j) * (set_tap(j) + 1) * set_tap(i) / 2 26 else 27 cnt += set_tap(remain - (i + j)) * set_tap(j) * set_tap(i) 28 end 29 } 30 } 31 @memo[remain] = cnt 32end 33 34puts set_tap(N) 35
2口や3口の場合の初めに書いてある
(1..(remain / 2)) や (1..(remain / 3)) が
タップの必要となる最大の個数?かとも思ったのですが、その後の場合分けも含め、全く理解できません。
どなたか解説宜しくお願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/01/06 05:50