fork download
  1. # 着目しているグループの最も大きなインデックスが k
  2. # b_k = b, b1 + b2 + … + b_k = m
  3. def calc(b, m, k)
  4. @memo[b | m << @shift | k << 2 * @shift] ||= begin
  5. # r はグループの要素数。まず取り得る最小値とする
  6. r = [m - k * (b - 1), 1].max
  7. m -= b * r
  8. k -= r
  9. denom = @fac[r] * @fac[b] ** r
  10. sum = 0
  11. # このループ1周ごとにグループの要素数 r を1ずつふやしていく
  12. while m >= b do
  13. sum += (-(-m / k)...b).inject(0) {|s, c| s + calc(c, m, k)} / denom
  14. m -= b
  15. k -= 1
  16. denom *= (r += 1) * @fac[b]
  17. end
  18. # グループの要素数が最大値を取る場合
  19. # 上で説明したように簡単に計算できる
  20. sum + @num / (denom * @fac[k] * @fac[m]) * k ** m
  21. end
  22. end
  23.  
  24. # F(n) を文字列で返す
  25. def f(n)
  26. # 階乗 @fac[k] = k!
  27. @fac = (1..[n, 10].max).each_with_object([1]) {|k, fc| fc << k * fc.last}
  28. @num = @fac[n] * @fac[10]
  29. @memo = {}
  30. @shift = n.to_s(2).size
  31. (-(-n / 10)..n).inject(0) {|s, b| s + b * calc(b, n, 10)}.
  32. to_s.insert(-n - 1, '.').sub(/\.?0*$/, '')
  33. end
  34.  
  35. puts f(6)
  36. puts f(12)
  37. puts f(100)
Success #stdin #stdout 0.17s 10824KB
stdin
Standard input is empty
stdout
2.01966
3.10849098132
15.1245274288119445948621344615506925019293897824748481734115430097323521731459481049200700247839938