2684 - Hard ssc

From Bitnami MediaWiki

Se dă un șir de n numere naturale. Șirul poate fi partiționat în mai multe moduri într-un număr de subșiruri strict crescătoare. De exemplu, șirul 4 6 2 5 8 1 3 7 poate fi partiționat astfel: 4 6 8 (primul subșir), 2 5 7 (al doilea) și 1 3 (al treilea). O altă modalitate este formând patru subșiruri: 4 5 7, 6 8, 2 3 și 1.

Cerinţa[edit | edit source]

Să se determine numărul minim de subșiruri strict crescătoare în care se poate partiționa șirul.

Date de intrare[edit | edit source]

Programul citește de la tastatură numărul n, iar apoi șirul de n numere naturale, separate prin spații.

Date de ieșire[edit | edit source]

Programul va afișa pe ecran numărul minim de subșiruri strict crescătoare în care se poate partiționa șirul.

Restricţii şi precizări[edit | edit source]

  • 1 ⩽ n ⩽ 100.000
  • cele n numere citite vor fi mai mici decât 100.000
  • Un subșir se obține dintr-un șir prin eliminarea a zero, unul, sau mai multe elemente.

Exemplu 1[edit | edit source]

Intrare
8
4 6 2 5 8 1 3 7
Iesire
Datele de intrare corespund restrictiilor impuse
3


Exemplu 2[edit | edit source]

Intrare
100002
12 12
Iesire
Datele de intrare nu corespund restrictiilor impuse


Rezolvare[edit | edit source]

<syntaxhighlight lang="python" line> from bisect import bisect_left


def numar_minim_subsecvente(n, sir):

   # Calculează numărul minim de subșiruri strict crescătoare în care se poate partiționa șirul.
   subsecvente = [0] * n
   lungime = 1
   # Primul element al sirului este întotdeauna o subsecvență în sine
   subsecvente[0] = sir[0]
   for i in range(1, n):
       # Dacă elementul curent este mai mare decât ultimul element al subsecvenței curente,
       # îl adăugăm la sfârșitul subsecvenței și creștem lungimea acesteia
       if sir[i] > subsecvente[lungime - 1]:
           subsecvente[lungime] = sir[i]
           lungime += 1
       else:
           # Dacă elementul curent este mai mic sau egal cu ultimul element al subsecvenței curente,
           # înlocuim cel mai mare element care este mai mic sau egal cu elementul curent
           j = bisect_left(subsecvente, sir[i], 0, lungime)
           subsecvente[j] = sir[i]
   return lungime


def main():

   n = int(input().strip())
   sir = list(map(int, input().split()))
   # Verifică dacă datele de intrare respectă restricțiile
   if not (1 <= n <= 100000 and all(0 <= x < 100000 for x in sir)):
       print("Datele de intrare nu corespund restrictiilor impuse\n")
       return
   print("Datele de intrare corespund restrictiilor impuse\n")
   numar = numar_minim_subsecvente(n, sir)
   print(f"{numar}\n")


if __name__ == "__main__":

   main()


</syntaxhighlight>