AtCoder Beginner Contest 350 E

https://atcoder.jp/contests/abc350/tasks/abc350_e

2番目を選んだ時、nのときの期待値は E_n = (E_n+E_{\lfloor{n/2}\rfloor} + \cdots + E_{\lfloor{n/6}\rfloor})/6 + Yなので、
 \displaystyle E_n = \frac{1}{5}\sum_{b=2}^6{E_{\lfloor{n/b}\rfloor}} + \frac{6}{5}Y
となります。取り得るnのは、 \lfloor{N/a}\rfloorとしたときのaが \frac{1}{6}\log_2{N}\log_3{N}\log_5{N}程度で、これが約10000です。また、aが違っても \lfloor{N/a}\rfloorが同じことが多いので、さらに取り得るnは少なくなって、十分に速いです。
結局、
 \displaystyle E_0 = 0
 \displaystyle E_n = \min{(E_{\lfloor{n/2}\rfloor} + X, \frac{1}{5}\sum_{b=2}^6{E_{\lfloor{n/b}\rfloor}} + \frac{6}{5}Y)}
となります。

// Toward 0
#![allow(non_snake_case)]


//////////////////// library ////////////////////

fn read<T: std::str::FromStr>() -> T {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).ok();
    line.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace()
            .map(|e| e.parse().ok().unwrap()).collect()
}


//////////////////// Game ////////////////////

use std::collections::HashMap;

struct Game {
    N: u64,
    A: u64,
    X: f64,
    Y: f64,
    E: HashMap<u64, f64>
}

impl Game {
    fn exp_value(&mut self, n: u64) -> f64 {
        if n == 0 {
            return 0.0
        }
        
        match self.E.get(&n) {
            Some(e) => *e,
            None    => {
                let e1 = self.exp_value(n/self.A) + self.X;
                let e2 = (2..7).map(|b| self.exp_value(n/b)).sum::<f64>() * 0.2 +
                                                                self.Y * 1.2;
                let e = if e1 < e2 { e1 } else { e2 };
                self.E.insert(n, e);
                e
            }
        }
    }
    
    fn read() -> Game {
        let v = read_vec();
        let (N, A, X, Y) = (v[0], v[1], v[2] as f64, v[3] as f64);
        let E = HashMap::new();
        Game { N, A, X, Y, E }
    }
}

//////////////////// process ////////////////////

fn F(mut game: Game) -> f64 {
    game.exp_value(game.N)
}

fn main() {
    let game = Game::read();
    println!("{}", F(game))
}