Adilbek's house is located on a street which can be represented as the OX axis. This street is really dark, so Adilbek wants to install some post lamps to illuminate it. Street has $n$ positions to install lamps, they correspond to the integer numbers from $0$ to $n - 1$ on the OX axis. However, some positions are blocked and no post lamp can be placed there.

There are post lamps of different types which differ only by their power. When placed in position $x$, post lamp of power $l$ illuminates the segment $[x; x + l]$. The power of each post lamp is always a positive integer number.

The post lamp shop provides an infinite amount of lamps of each type from power $1$ to power $k$. Though each customer is only allowed to order post lamps of exactly one type. Post lamps of power $l$ cost $a_l$ each.

What is the minimal total cost of the post lamps of exactly one type Adilbek can buy to illuminate the entire segment $[0; n]$ of the street? If some lamps illuminate any other segment of the street, Adilbek does not care, so, for example, he may place a lamp of power $3$ in position $n - 1$ (even though its illumination zone doesn't completely belong to segment $[0; n]$).


-----Input-----

The first line contains three integer numbers $n$, $m$ and $k$ ($1 \le k \le n \le 10^6$, $0 \le m \le n$) — the length of the segment of the street Adilbek wants to illuminate, the number of the blocked positions and the maximum power of the post lamp available.

The second line contains $m$ integer numbers $s_1, s_2, \dots, s_m$ ($0 \le s_1 < s_2 < \dots s_m < n$) — the blocked positions.

The third line contains $k$ integer numbers $a_1, a_2, \dots, a_k$ ($1 \le a_i \le 10^6$) — the costs of the post lamps.


-----Output-----

Print the minimal total cost of the post lamps of exactly one type Adilbek can buy to illuminate the entire segment $[0; n]$ of the street.

If illumintaing the entire segment $[0; n]$ is impossible, print -1.


-----Examples-----
Input
6 2 3
1 3
1 2 3

Output
6

Input
4 3 4
1 2 3
1 10 100 1000

Output
1000

Input
5 1 5
0
3 3 3 3 3

Output
-1

Input
7 4 3
2 4 5 6
3 14 15

Output
-1

Difficulty: HARD
Tags: Complete search

Greedy algorithms
Skill types: Complete search

Greedy algorithms

Starter code:

Solutions:
import sys
(n, m, k) = list(map(int, input().split()))
s = list(map(int, sys.stdin.readline().split()))
a = list(map(int, sys.stdin.readline().split()))
if m > 0 and s[0] == 0:
	print('-1')
else:
	block = [-1] * n
	for i in range(m):
		if block[s[i] - 1] == -1:
			block[s[i]] = s[i] - 1
		else:
			block[s[i]] = block[s[i] - 1]
	MAX_COST = 10000000000000.0
	max_inr = 0
	if m > 0:
		inr = 1
		prev = s[0]
		for i in range(1, m):
			if s[i] == prev + 1:
				inr += 1
			else:
				if inr > max_inr:
					max_inr = inr
				inr = 1
			prev = s[i]
		if inr > max_inr:
			max_inr = inr
	best_cost = []
	for i in range(k):
		if i < max_inr:
			best_cost.append(MAX_COST)
		else:
			best_cost.append(a[i] * -(-n // (i + 1)))
	min_cost = MAX_COST
	for i in range(k):
		test = i
		if best_cost[test] >= min_cost:
			continue
		t_size = test + 1
		pos = 0
		count = 1
		while pos < n:
			new_pos = pos + t_size
			if new_pos >= n:
				break
			if block[new_pos] != -1:
				if block[new_pos] <= pos:
					raise Exception('smth went wrong')
				new_pos = block[new_pos]
			pos = new_pos
			count += 1
		min_cost = min(min_cost, a[test] * count)
	if min_cost < MAX_COST:
		print(min_cost)
	else:
		print('-1')


import sys
from math import ceil
(n, m, k) = map(int, sys.stdin.readline().split())
places = [True for _ in range(n)]
for x in map(int, sys.stdin.readline().split()):
	places[x] = False
costs = list(map(int, sys.stdin.readline().split()))
if not places[0]:
	print(-1)
	sys.exit(0)
longest_streak = 0
streak = 0
for p in places:
	if not p:
		streak += 1
	else:
		longest_streak = max(longest_streak, streak)
		streak = 0
longest_streak = max(streak, longest_streak)
prev = [i for i in range(n)]
last = 0
for i in range(n):
	if places[i]:
		last = i
	prev[i] = last
best_cost = float('inf')
for lamp in range(k, longest_streak, -1):
	min_cost = ceil(n / lamp) * costs[lamp - 1]
	if min_cost >= best_cost:
		continue
	cost = costs[lamp - 1]
	reach = lamp
	fail = False
	while reach < n:
		if prev[reach] + lamp <= reach:
			fail = True
			break
		reach = prev[reach] + lamp
		cost += costs[lamp - 1]
		if cost + ceil((n - reach) / lamp) * costs[lamp - 1] >= best_cost:
			fail = True
			break
	if not fail:
		best_cost = min(best_cost, cost)
print(best_cost if best_cost != float('inf') else -1)


def i_ints():
	return list(map(int, input().split()))

def next_free_from_blocks(n, blocks):
	m = 0
	res = list(range(n + 1))
	for i in reversed(blocks):
		res[i] = res[i + 1]
		if res[i] - i > m:
			m = res[i] - i
	return (res, m)
(n, m, k) = i_ints()
blocks = i_ints()
costs = i_ints()
(next_free, max_block_len) = next_free_from_blocks(n, blocks)
blocks.append(n + 1)
if m == 0:
	max_block_len = 0
if max_block_len >= k or blocks[0] == 0:
	print(-1)
else:
	minimal_costs = [c * ((n + l - 1) // l) for (l, c) in enumerate(costs, 1)]
	maximal_costs = [c * 2 * ((n + l) // (l + 1)) for (l, c) in enumerate(costs, 1)]
	max_costs = min(maximal_costs[max_block_len:])
	possible = [i + 1 for i in range(max_block_len, k) if minimal_costs[i] <= max_costs]
	for i in range(len(possible) - 1)[::-1]:
		if costs[possible[i] - 1] > costs[possible[i + 1] - 1]:
			del possible[i]

	def calc(l):
		count = 1
		pos = n - l
		while pos > 0:
			pos = next_free[pos] - l
			count += 1
		return count
	print(min((calc(l) * costs[l - 1] for l in possible)))


import sys
from array import array
(n, m, k) = map(int, input().split())
block = list(map(int, input().split()))
a = [0] + list(map(int, input().split()))
if block and block[0] == 0:
	print(-1)
	exit()
prev = array('i', list(range(n)))
for x in block:
	prev[x] = -1
for i in range(1, n):
	if prev[i] == -1:
		prev[i] = prev[i - 1]
inf = ans = 10 ** 18
for i in range(1, k + 1):
	s = 0
	cost = 0
	while True:
		cost += a[i]
		t = s + i
		if t >= n:
			break
		if prev[t] == s:
			cost = inf
			break
		s = prev[t]
	ans = min(ans, cost)
print(ans if ans < inf else -1)


import sys
from math import ceil
(n, t, k) = list(map(int, sys.stdin.readline().split()))
places = [True for _ in range(n)]
for x in map(int, sys.stdin.readline().split()):
	places[x] = False
costs = list(map(int, sys.stdin.readline().split()))
if not places[0]:
	print(-1)
	return
prev = [i for i in range(n)]
last = 0
for i in range(n):
	if places[i]:
		last = i
	prev[i] = last
best_cost = float('inf')
for lamp in range(k, 0, -1):
	min_cost = ceil(n / lamp) * costs[lamp - 1]
	if min_cost >= best_cost:
		continue
	cost = costs[lamp - 1]
	reach = lamp
	fail = False
	while reach < n:
		if prev[reach] + lamp <= reach:
			fail = True
			break
		reach = prev[reach] + lamp
		cost += costs[lamp - 1]
		if cost + ceil((n - reach) / lamp) * costs[lamp - 1] >= best_cost:
			fail = True
			break
	if not fail:
		best_cost = min(best_cost, cost)
print(best_cost if best_cost != float('inf') else -1)


import sys
from sys import stdin, stdout
(n, m, k) = list(map(int, stdin.readline().split(' ')))
t22 = stdin.readline()
bl = []
if len(t22.strip()) == 0:
	bl = []
else:
	bl = list(map(int, t22.split(' ')))
bd = {}
for i in bl:
	bd[i] = 1
cost = list(map(int, stdin.readline().split(' ')))
dp = [-1 for i in range(n)]
dp[0] = 0

def formdp():
	nonlocal dp
	for i in range(1, n):
		if i in bd:
			t1 = i
			while dp[t1] == -1:
				t1 -= 1
			dp[i] = dp[t1]
		else:
			dp[i] = i

def get(i):
	f = 1
	p = 0
	while p + i < n:
		if dp[p + i] == p:
			return -1
		else:
			p = dp[p + i]
			f += 1
	return f
if True:
	if 0 in bd:
		print(-1)
	else:
		formdp()
		minf = [0 for i in range(k + 1)]
		for i in range(1, k + 1):
			minf[i] = get(i)
		ans = -1
		for i in range(1, len(minf)):
			if minf[i] != -1:
				if ans == -1:
					ans = minf[i] * cost[i - 1]
				else:
					ans = min(ans, minf[i] * cost[i - 1])
		if ans == -1:
			print(-1)
		else:
			print(ans)


(n, m, k) = map(int, input().split())
free = [True] * n
for i in list(map(int, input().split())):
	free[i] = False
a = list(map(int, input().split()))
last_lamp = [-1] * n
for i in range(n):
	if free[i]:
		last_lamp[i] = i
	if i > 0 and (not free[i]):
		last_lamp[i] = last_lamp[i - 1]
ans = int(1e+100)
for i in range(1, k + 1):
	(last, prev) = (0, -1)
	cur = 0
	while last < n:
		if last_lamp[last] <= prev:
			cur = None
			break
		prev = last_lamp[last]
		last = prev + i
		cur += 1
	if cur is not None:
		ans = min(ans, a[i - 1] * cur)
if ans == int(1e+100):
	print(-1)
else:
	print(ans)