Problem:
Score : 300 points

Problem Statement

You've come to your favorite store Infinitesco to buy some ice tea.

The store sells ice tea in bottles of different volumes at different costs.
Specifically, a 0.25-liter bottle costs Q yen, a 0.5-liter bottle costs H yen, a 1-liter bottle costs S yen, and a 2-liter bottle costs D yen.
The store has an infinite supply of bottles of each type.

You want to buy exactly N liters of ice tea. How many yen do you have to spend?

Constraints

1 \leq Q, H, S, D \leq 10^8

1 \leq N \leq 10^9

All input values are integers.

Input

Input is given from Standard Input in the following format:

Q H S D
N

Output

Print the smallest number of yen you have to spend to buy exactly N liters of ice tea.

Sample Input 1

20 30 70 90
3

Sample Output 1

150

Buy one 2-liter bottle and two 0.5-liter bottles. You'll get 3 liters for 90 + 30 + 30 = 150 yen.

Sample Input 2

10000 1000 100 10
1

Sample Output 2

100

Even though a 2-liter bottle costs just 10 yen, you need only 1 liter.
Thus, you have to buy a 1-liter bottle for 100 yen.

Sample Input 3

10 100 1000 10000
1

Sample Output 3

40

Now it's better to buy four 0.25-liter bottles for 10 + 10 + 10 + 10 = 40 yen.

Sample Input 4

12345678 87654321 12345678 87654321
123456789

Sample Output 4

1524157763907942

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::fmt::{Debug, Display};
use std::io::{self, Read};
use std::str::{self, FromStr};


fn solve(q: u64, h: u64, s: u64, d: u64, n: u64) -> u64 {
    let q_per_2l = 8 * q;
    let h_per_2l = 4 * h;
    let s_per_2l = 2 * s;
    let d_per_2l = d;
    let min_per_2l = *[q_per_2l, h_per_2l, s_per_2l, d_per_2l]
        .into_iter()
        .min()
        .unwrap();

    if n % 2 == 0 {
        if min_per_2l == d_per_2l {
            d * n / 2
        } else if min_per_2l == s_per_2l {
            s * n
        } else if min_per_2l == h_per_2l {
            2 * h * n
        } else {
            4 * q * n
        }
    } else {
        if min_per_2l == d_per_2l {
            let min_per_2l_ex_d = *[q_per_2l, h_per_2l, s_per_2l].into_iter().min().unwrap();
            n / 2 * d +
                if min_per_2l_ex_d == q_per_2l {
                    4 * q
                } else if min_per_2l_ex_d == h_per_2l {
                    2 * h
                } else {
                    s
                }
        } else if min_per_2l == s_per_2l {
            s * n
        } else if min_per_2l == h_per_2l {
            2 * h * n
        } else {
            4 * q * n
        }
    }
}


fn main() {
    let stdin = io::stdin();
    let mut sc = Scanner::new(stdin.lock().bytes());
    println!(
        "{}",
        solve(sc.next(), sc.next(), sc.next(), sc.next(), sc.next())
    );
}


struct Scanner<R: Read> {
    buf: Vec<u8>,
    bytes: io::Bytes<R>,
}

#[allow(dead_code)]
impl<R: Read> Scanner<R> {
    fn new(bytes: io::Bytes<R>) -> Self {
        Scanner {
            buf: Vec::with_capacity(256),
            bytes: bytes,
        }
    }

    fn next<T: FromStr>(&mut self) -> T
    where
        <T as FromStr>::Err: Debug,
    {
        self.buf.clear();
        for c in self.bytes
            .by_ref()
            .map(|c| c.unwrap())
            .skip_while(|&c| c == ' ' as u8 || c == '\n' as u8)
            .take_while(|&c| !(c == ' ' as u8 || c == '\n' as u8))
        {
            self.buf.push(c);
        }
        str::from_utf8(&self.buf).unwrap().parse().unwrap()
    }

    fn vec<T: FromStr>(&mut self, n: usize) -> Vec<T>
    where
        <T as FromStr>::Err: Debug,
    {
        (0..n).map(|_| self.next()).collect()
    }

    fn pairs<A: FromStr, B: FromStr>(&mut self, n: usize) -> Vec<(A, B)>
    where
        <A as FromStr>::Err: Debug,
        <B as FromStr>::Err: Debug,
    {
        (0..n).map(|_| (self.next(), self.next())).collect()
    }

    fn trios<A: FromStr, B: FromStr, C: FromStr>(&mut self, n: usize) -> Vec<(A, B, C)>
    where
        <A as FromStr>::Err: Debug,
        <B as FromStr>::Err: Debug,
        <C as FromStr>::Err: Debug,
    {
        (0..n)
            .map(|_| (self.next(), self.next(), self.next()))
            .collect()
    }

    fn mat<T: FromStr>(&mut self, m: usize, n: usize) -> Vec<Vec<T>>
    where
        <T as FromStr>::Err: Debug,
    {
        (0..n).map(|_| self.vec(m)).collect()
    }
}


#[allow(dead_code)]
fn print_foreach<T: Display>(answer: &[T]) {
    for x in answer {
        println!("{}", x);
    }
}


#[allow(dead_code)]
fn print_yn(answer: bool, yes: &str, no: &str) {
    println!("{}", if answer { yes } else { no });
}


#[allow(dead_code)]
fn print_or<T: Display>(answer: &Option<T>, or: &T) {
    match *answer {
        Some(ref x) => println!("{}", x),
        None => println!("{}", or),
    }
}