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 C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;

#define lowbit(x) ((x) & (-x))

const int maxn = (int)(2e5) + 5;
const double pi = acos(-1.0);

int tbX[maxn], tbY[maxn], C[maxn], f[maxn];

struct node {
	int x, y;
} p[maxn];

bool operator < (node a, node b) {
	return a.x != b.x ? a.x < b.x : a.y < b.y;
}

inline int hs(int a[], int x) {
	return lower_bound(a + 1, a + a[0] + 1, x) - a;
}

inline int gmx(int x) {
	if (!x) return -233;
	int ret = 0; for (; x; x -= lowbit(x)) ret = max(ret, C[x]); return ret;	
}

inline void add(int x, int v) {
	for (; x <= tbY[0]; x += lowbit(x)) C[x] = max(C[x], v);
}

int main() {
	int Xs, Ys, Xt, Yt;
	scanf("%d%d%d%d", &Xs, &Ys, &Xt, &Yt);
	int n, m = 0;
	scanf("%d", &n);
	int Xl = Xs, Xr = Xt, Yl = Ys, Yr = Yt;
	if (Xl > Xr) swap(Xl, Xr);
	if (Yl > Yr) swap(Yl, Yr);
	for (int i = 1; i <= n; ++i) {
		int x, y; scanf("%d%d", &x, &y);
		if (Xl <= x && x <= Xr && Yl <= y && y <= Yr) {
			++m; p[m].x = x - Xl; p[m].y = y - Yl;
		}
	}
	int h = Xr - Xl, w = Yr - Yl;
	if (Xs > Xt) {
		for (int i = 1; i <= m; ++i) p[i].x = h - p[i].x;
	}
	if (Ys > Yt) {
		for (int i = 1; i <= m; ++i) p[i].y = w - p[i].y;
	}
	tbX[++tbX[0]] = 0; tbY[++tbY[0]] = 0;
	for (int i = 1; i <= m; ++i) tbX[++tbX[0]] = p[i].x, tbY[++tbY[0]] = p[i].y;
	tbX[++tbX[0]] = h; tbY[++tbY[0]] = w;
	sort(tbX + 1, tbX + tbX[0] + 1);
	tbX[0] = unique(tbX + 1, tbX + tbX[0] + 1) - tbX - 1;
	sort(tbY + 1, tbY + tbY[0] + 1);
	tbY[0] = unique(tbY + 1, tbY + tbY[0] + 1) - tbY - 1;
	for (int i = 1; i <= m; ++i) p[i].x = hs(tbX, p[i].x), p[i].y = hs(tbY, p[i].y);
	h = hs(tbX, h); w = hs(tbY, w);
	sort(p + 1, p + m + 1); int X = 1, Y = 1;
	for (int i = 1; i <= m; ++i) {
		f[i] = gmx(p[i].y - 1) + 1; add(p[i].y, f[i]); 
		if (p[i].x == h) Y = max(Y, p[i].y); if (p[i].y == w) X = max(X, p[i].x); 
	} 
	double ret = m >= min(h, w) ? -(pi * 10 - 20) : 0;
	for (int i = 1; i <= m; ++i) {
		ret = max(ret, (20.0 - pi * 5) * f[i] - (pi * 10 - 20)); 
		if (tbX[p[i].x] + 1 < tbX[h] || tbY[p[i].y] + 1 < tbY[w] || p[i].x >= X || p[i].y >= Y) {
			int dt = (p[i].x == X || p[i].y == Y); ret = max(ret, (20 - pi * 5) * (f[i] + dt));
		}
	}
	return printf("%.10lf\n", 100.0 * (tbX[h] + tbY[w]) - ret), 0;
}