---
title: 「プログラマのための論理パズル」(1)甘いもの好き
tags: []
categories: ["Programming", "Algorithm", "Puzzles"]
date: 2011-05-23T16:05:58Z
updated: 2011-05-23T16:58:02Z
---
### ウォームアップ問題
まずはウォームアップ問題を簡単に書く。
ケーキが2つあって、Aさんはケーキを好きな大きさで2つに切る。Bさんは切られたケーキのどっちかを先に選べる権利を1個目のケーキで使うか2個目のケーキで使うかの選択権がある。1個目のケーキを先に選んだ場合、2個目は後に選ばないといけない。Aさんは1個目の選択が終わった後に2個目のケーキを切る。
Aさん、Bさんともに自分ができるだけ大きいケーキを食べたいと思っている。
Aさんが食べるケーキを最大にするにはどういう戦略をとればいいか。そのときAさんが食べることができるケーキは何個か?
【解答】
1個目のケーキを`f`と`1-f`に切り分ける。ここで`f`は大きい部分で、`1/2 <= f <= 1`を満たす(`f=1`といのはもう片方が無視できるくらい小さく切った場合)。
先にAさんが選ぶ場合、大きい方を選ぶので`f`を取ることになる。2個目のケーキではBさんが大きい方をとるので、Bさんの取り分が最少になるように1/2できる。Aさんの食べるケーキを`p`個とすると、
`p = f + 1/2` … ①
となる。
先にBさんが選ぶ場合、小さい方が残るので`1-f`を取ることになる。2個目はケーキでAさんは大きい方を取れるのでできるだけ大きく切る。Bさんの分は無視できるほど小さくなる。このときのAさんのケーキは
`p = (1-f) + 1 = 2 - f` … ②
となる。
①と②が同じ場合、Bさんがどっちを選んでもAさんは最大個のケーキを食べることができる。
つまり、`f = 3/4`で切ると、`p = 5/4`個食べることができる。
### 本題
では本題。
ウォームアップ問題同様に
- ケーキが3個になった場合
- ケーキが7個になった場合
どうすれば良いか?ついでにAさんはBさんよりどのくらい多く食べることができるか。
ここでAさんが先に選べる権利は1回だけで、残りはBさんが先に選べるとする。
【makingの解】
ケーキ3個の場合、同じように`f`と`1-f`に切り分ける。
最初にAさんが選ぶ場合、残り2個はBさんが先に選ぶのでずっと半分に切る。
最初にBさんが選ぶ場合、残り2個の状況はウォームアップ問題と同じになるので`f'=3/4`で2個目を切ればのこり5/4個ゲットできる。
ということで
`p = f + 1/2 + 1/2 = (1-f) + 5/4`
を解けばOK。
最初に
`f = 5/8`できれば、`p = 13/8`個食べることができる。
----
あとは帰納的に解ける。
n個のケーキ
最初にAさんが選ぶ場合、残り(n-1)個はBさんが先に選ぶのでずっと半分に切る。
最初にBさんが選ぶ場合、残り(n-1)個の状況はケーキが(n-1)個のときと同じになる。
ケーキがn個のときのAさんの食べることができる最大の個数を`p(n)`とすると
`p(n) = f + (n-1)*1/2 = (1-f) + p(n-1)`
`p(2) = 5/4`
を解けば良い。
`p(n) = (n+1)*1/4 + p(n-1)*1/2`
`f = (3-n)*1/4 + p(n-1)*1/2`
AさんがBさんより多く食べることができる個数を`m(n)`とすると
`m(n) = p(n) - (n - p(n)) = 2*p(n) - n`
Clojureで解いてみる(分数が使えるので)
;; n < 2の場合は考えない。。
(defn p [n]
(if (> n 2)
(+ (/ (+ n 1) 4) (/ (p (- n 1)) 2))
5/4))
;; 何度も使うのでメモ化
(def p (memoize p))
(defn f [n] (+ (/ (- 3 n) 4) (/ (p n) 2)))
;; 表示
(doseq [i (range 2 8)]
(let [f (f i) p (p i)]
(printf "n=%d,f=%6s,p=%7s,m=%4s%n" i f p (- (* 2 p) i))))
実行結果
n=2,f= 3/4,p= 5/4,m= 1/2
n=3,f= 5/8,p= 13/8,m= 1/4
n=4,f= 9/16,p= 33/16,m= 1/8
n=5,f= 17/32,p= 81/32,m=1/16
n=6,f= 33/64,p= 193/64,m=1/32
n=7,f=65/128,p=449/128,m=1/64
こんな感じ。高校数学みたいっすな。
----
面白かったらぽちって↓