Skip to content

Instantly share code, notes, and snippets.

@obelisk68
Last active April 18, 2018 02:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save obelisk68/2ccf7badb4968620aeb9538cdbab7c9e to your computer and use it in GitHub Desktop.
Save obelisk68/2ccf7badb4968620aeb9538cdbab7c9e to your computer and use it in GitHub Desktop.
公平に分けられたケーキ
#(x, y)のケーキを切ってできる全ての (面積, 切った長さの合計) のペアを返す
#ただし面積はここでカットした人の総計
def cut(x, y)
x, y = y, x if x < y
return @memo[[x, y]] if @memo.has_key?([x, y])
return {1 => 1} if x == 2 and y == 1
result = {}
#前の人がカットしたところから自分の分を求める
#「if result[square] > length」は効果の大きい枝刈り(切り口の長さの総和が最小になるものだけ残す)
calc = proc do |s, t|
cut(s, t).each do |sqar, ln|
square = x * y - sqar
length = ln + s
result[square] = length if !result.has_key?(square) or result[square] > length
end
end
#可能なあらゆる場合でケーキを切る
(x / 2).times {|i| calc.(y, x - i - 1)}
(y / 2).times {|i| calc.(x, y - i - 1)}
@memo[[x, y]] = result
end
X, Y = 16, 12
@memo = {}
result = cut(X, Y)
p result.select {|sqar, _| sqar == X * Y / 2} #=>{96=>47}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment