-
Notifications
You must be signed in to change notification settings - Fork 23
/
acoperire.py
87 lines (60 loc) · 2.42 KB
/
acoperire.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
"""
Soluția greedy:
Sortăm intervalele după timpul de început.
Fie [a, b] intervalul curent pe care încercăm să-l acoperim.
Mergem în ordine prin intervale, și alegem intervalul care
începe înainte de „a” și acoperă cel mai mult (se termină cel mai târziu).
După ce l-am ales, îl punem în soluție, capătul lui din dreapta devine
noul „a”, și continuăm algoritmul.
Demonstrație corectitudine:
Notăm cu [A, B] intervalul curent pe care vrem să-l acoperim.
1) Soluția construită de greedy este corectă:
Întotdeauna alegem un interval dintre cele care încep la stânga lui A,
deci nu formăm o soluție invalidă.
Deasemenea, parcurgem liniar toate intervalele, nu putem omite vreunul
care ar apărea într-o soluție.
2) Presupunem că soluția greedy nu ar fi optimă.
Să zicem că (x, y) ar fi primul interval ales de greedy care diferă,
și (x', y') ar fi intervalul ales de soluția optimă.
Fie A capătul curent din stânga al intervalului pe care vrem să-l acoperim.
Avem că:
x < A < y (pentru că soluția greedy este corectă)
x' < A < y' (pentru că soluția optimă este corectă)
y' <= y (pentru că la greedy alegem intervalul
care să aibă y maxim)
Deoarece y' <= y, indiferent ce alte intervale mai alege soluția optimă mai încolo,
putem să înlocuim intervalul [x', y'] cu [x, y] și obținem că soluția greedy
este mai bună decât cea optimă, contradicție.
"""
fin = open('acoperire.txt')
lines = map(str.strip, fin)
a, b = map(int, next(lines).split())
n = int(next(lines))
intervals = [tuple(map(int, next(lines).split())) for _ in range(n)]
intervals.sort()
# print('Intervalele sortate:', *intervals)
def find_next_interval(start):
current = start
max_index = current
while current < len(intervals) and intervals[current][0] <= a:
if intervals[current][1] > intervals[max_index][1]:
max_index = current
current += 1
if current < len(intervals) and intervals[max_index][0] > a:
return -1
return max_index
solution = []
ok = True
index = 0
while ok and a < b:
index = find_next_interval(index)
if index == -1:
ok = False
break
a = intervals[index][1]
solution.append(intervals[index])
index += 1
if ok:
print(*solution)
else:
print('Nu există soluție')