module Cp : sig val string_1_list_of_string: string -> string list val split_on_char: char -> string -> string list val read_int_list: unit -> int list end = struct let string_1_list_of_string x = String.to_seq x |> List.of_seq |> List.map (String.make 1);; let split_on_char sep s = (* from OCaml Standard Library 4.12 *) let r = ref [] in let j = ref (String.length s) in for i = String.length s - 1 downto 0 do if String.unsafe_get s i = sep then begin r := String.sub s (i + 1) (!j - i - 1) :: !r; j := i end done; String.sub s 0 !j :: !r;; let read_int_list () = read_line () |> split_on_char ' ' |> List.map int_of_string;; end let memo_rec f = let h = Hashtbl.create 10000 in let rec g x = let try_find = Hashtbl.find_opt h x in match try_find with | Some (x) -> x | None -> let y = f g x in Hashtbl.add h x y ; y in g;; let sushi_memo sushi_array = let rec fib self = fun x -> if x < 1 then 0 else max ((self (x - 2)) + sushi_array.(x - 1)) (self (x - 1)) in memo_rec fib;; let () = let n = read_int () in let sushi_array = Cp.read_int_list () |> Array.of_list in let lets_sushi_party = sushi_memo sushi_array in lets_sushi_party n |> print_int; print_newline ();;