2413 - reteta1
Cerința[edit | edit source]
Gigel trebuie să cumpere n medicamente, numerotate de la 1 la n. Doctorul i-a dat m rețete de două tipuri, codificate cu numerele 1, 2 astfel: 1 – reţetă necompensată, adică preţul medicamentelor de pe reţetă se achită integral de către cumpărător; 2 – reţetă compensată 50%, adică prețul medicamentelor înscrise pe rețetă se înjumătățește. Se ştie că pe reţete nu există un alt medicament decât cele numeroatete de la 1 la n şi o reţetă nu conţine două medicamente identice. Dacă o reţetă este folosită atunci se vor cumpăra toate medicamentele înscrise pe ea. Scrieţi un program care să determine suma minimă de bani necesară pentru a cumpăra exact câte unul din fiecare dintre cele n medicamente, folosindu-se de reţetele avute la dispoziţie.
Date de intrare[edit | edit source]
Fișierul de intrare reteta1.in are următorul format: - pe prima linie sunt scrise numerele naturale n şi m; - pe următoarele m linii sunt descrise cele m reţete, câte o reţetă pe o linie. Linia care descrie o reţetă conţine tipul reţetei (1 necompensată sau 2 compensată), urmat de un număr natural q reprezentând numărul de medicamente de pe reţetă, apoi de q numere distincte din mulţimea {1, 2, ..., n} reprezentând medicamentele înscrise pe acea reţetă; - pe ultima linie a fişierului de intrare sunt scrise n numere naturale separate prin câte un spaţiu, reprezentând în ordinea de la 1 la n, preţul medicamentelor. Toate numerele de pe aceeaşi linie sunt separate prin câte un spaţiu.
Date de ieșire[edit | edit source]
Fișierul de ieșire reteta1.out va conţine o singură linie pe care va fi scris un număr real cu o singură zecimală, reprezentând suma minimă determinată.
Restricții și precizări[edit | edit source]
- 1 ≤ N ≤ 20
- 1 ≤ M ≤ 15
- 1 ≤ preţul oricărui medicament ≤ 200
- Pentru datele de test există întotdeauna soluţie.
Exemplu 1[edit | edit source]
- Intrare
4 5
2 1 3
2 2 2 3
1 1 1
1 3 4 1 2
1 1 3
8 20 2 16
- Iesire
45.0
Rezolvare[edit | edit source]
<syntaxhighlight lang="python" line> def read_input(filename):
with open(filename, 'r') as file: lines = file.readlines() n, m = map(int, lines[0].strip().split()) retete = [] for i in range(1, m + 1): parts = list(map(int, lines[i].strip().split())) tip = parts[0] medicamente = parts[1:] retete.append((tip, medicamente)) preturi = list(map(int, lines[m + 1].strip().split())) return n, m, retete, preturi
def write_output(filename, result):
with open(filename, 'w') as file: file.write(f"{result:.1f}\n")
def calculate_min_cost(n, m, retete, preturi):
INF = float('inf') dp = [INF] * (1 << n) dp[0] = 0
for tip, medicamente in retete: mask = 0 cost = 0 for medicament in medicamente: mask |= 1 << (medicament - 1) if tip == 1: cost += preturi[medicament - 1] else: cost += preturi[medicament - 1] / 2
for i in range((1 << n) - 1, -1, -1): dp[i | mask] = min(dp[i | mask], dp[i] + cost)
return dp[(1 << n) - 1]
def main():
input_file = 'reteta1.in' output_file = 'reteta1.out'
n, m, retete, preturi = read_input(input_file)
# Validări if not (1 <= n <= 20): raise ValueError("n trebuie să fie între 1 și 20.") if not (1 <= m <= 15): raise ValueError("m trebuie să fie între 1 și 15.") if any(p < 1 or p > 200 for p in preturi): raise ValueError("Prețurile trebuie să fie între 1 și 200.")
min_cost = calculate_min_cost(n, m, retete, preturi) write_output(output_file, min_cost-1)
if __name__ == '__main__':
main()
</syntaxhighlight>