2056 - Popcorn
Cerința
Cu toții știm că popcornul este o adevărată delicatesă culinară. În pregătirile tale pentru lotul de anul acesta (și pentru petrecerile de după), ai făcut comandă de N
tipuri de floricele de porumb pentru microunde. Fiecare tip are asociate 3
valori:
A[i]
= Timpul (în secunde) la care orice floricică de acel tip “pocnește”;B[i]
= Timpul (în secunde) la care orice floricică de acel tip “se arde”;C[i]
= Cantitatea (în floricele) a respectivului tip.
Mai ai la dispoziție M
pungi pentru floricele de unică folosință de capacitate foarte mare (practic, infinită) și un cuptor cu microunde. Cum, bineînțeles, nimănui nu îi plac floricelele nefăcute sau cele arse, îți dorești să le partiționezi convenabil în cele M
pungi și apoi să le introduci pe rând în cuptorul cu microunde, setându-i un timp de preparare prep[i]
corespunzător, astfel încât după cele M
tranșe să obții cât mai multe floricele comestibile.
Formal, o floricică de tipul i
introdusă în punga j
, setată la timpul (în secunde) de preparare prep[j]
este comestibilă dacă și numai dacă A[i] ≤ prep[j] < B[i]
.
Fiind date cele N
tipuri de floricele și numărul de pungi disponibile, trebuie să găsești o partiție convenabilă și timpii optimi de preparare pentru fiecare pungă, astfel încât la final să obții numărul maxim de floricele comestibile, pe care să îl afișezi în fișierul de ieșire. Prea ușor!
Date de intrare
Fișierul de intrare popcorn.in
conține pe prima linie numerele naturale N
și M
, separate printr-un spațiu, cu semnificația din enunț. Pe următoarele N
linii se vor afla valorile A[i]
, B[i]
, C[i]
corespunzătoare fiecărui tip de floricele.
Date de ieșire
Fișierul popcorn.out
va conține un singur număr natural reprezentând numărul maxim de floricele comestibile care se poate obține.
Restricții și precizări
1 ≤ M ≤ N ≤ 200 000
1 ≤ A[i] < B[i] ≤ 200 000
- Numărul total de floricele nu depășește
109
- Unele pungi pot fi goale !
X = max{N, B[1], B[2], …, B[N]}
Exemplu 1
- Intrare
- 5 2
- 2 4 3
- 1 5 6
- 4 8 10
- 7 8 2
- 10 11 2
- Ieșire
- 21
Explicație
Avem 5
tipuri de floricele și 2
pungi disponibile.
Una din soluțiile posibile este:
- Punga
1
va conține tipurile1
și2
și va fi preparată la timpul3
. - Punga
2
va conține tipurile3, 4, 5
și va fi preparată la timpul7
.
Toate tipurile de floricele vor fi preparate cu succes, în afară de tipul 5
, care vor rămâne în stadiul de boabe.
Exemplu 2
- Intrare
- 3 3
- 1 2 2
- 2 3 3
- 1 3 5
- Ieșire
- 10
Explicație
Putem alege pungile astfel:
- Punga
1
va conține tipurile1, 3
și va fi preparată la timpul1
. - Punga
2
va conține tipul2
și va fi preparată la timpul2
. - Punga
3
va fi goală.
Exemplu 3
- Intrare
- 3 3
- 2 1 2
- 3 2 3
- 1 3 5
- Ieșire
- Date de intrare gresite!
Rezolvare
<syntaxhighlight lang="python" line="1">
- 2056 Popcorn
T_POCNIRE = 0 T_ARDERE = 1 CANTITATE = 2
def max_floricele_comestibile(n_tipuri, n_pungi, floricele):
nr = [[0 for j in range(50_000)] for i in range(n_tipuri)] for i in range(n_tipuri): for k in range(floricele[i][T_POCNIRE], floricele[i][T_ARDERE]): if k < floricele[i][T_ARDERE]: nr[i][k] = floricele[i][CANTITATE]
dinamic = [[0 for j in range(n_pungi+1)] for i in range(n_tipuri+1)] for i in range(1, n_tipuri+1): for j in range(1, n_pungi+1): for k in range(j, -1, -1): dinamic[i][j] = max(dinamic[i][j], dinamic[i-1][k] + sum(nr[i-1][:j-k])) return max(dinamic[-1])
def conditii(n_tipuri, n_pungi, tipuri_floricele):
for tip in tipuri_floricele: if not 1 <= tip[T_POCNIRE] < tip[T_ARDERE] <= 200_000: return False
if sum([tip[CANTITATE] for tip in tipuri_floricele]) > 10**9: return False
if not 1 <= n_pungi <= n_tipuri <= 200_000: return False
x = [tip[T_ARDERE] for tip in tipuri_floricele] x.append(n_tipuri)
x_max = max(x)
if not n_pungi <= x_max <= 50_000: return False
return True
def main():
n_tipuri, n_pungi = [int(x) for x in input().split(" ")]
floricele = []
for i in range(n_tipuri): a, b, c = [int(x) for x in input().split()] floricele.append([a, b, c])
if not conditii(n_tipuri, n_pungi, floricele): return print("Date de intrare gresite!")
print(max_floricele_comestibile(n_tipuri, n_pungi, floricele))
if __name__ == "__main__":
main()
</syntaxhighlight>