Vai al contenuto principale
ProdottiStrumenti desktopTASTECADVisualizzazione disegniTASTEFILESGestione fileTASTEFTPTrasferimento fileTASTESSHSpazio di lavoro remotoTASTEZIPCompressione ed estrazioneStrumenti per sviluppatoriTASTECODEAmbiente di sviluppo integrato per RustTASTESTUDIOAmbiente integrato di sviluppo e testTASTEETLIntegrazione dati (ETL)ServerTASTEREMOTEServer di desktop remotoTASTEGEOServer geospazialeTASTEMAILSpazio di lavoro emailIniziaDownloadDocumentazioneAcquistaTutti i prodotti
Marketplace
Notizie
TecnologiaNotizieNotizie di sviluppo di oggiDocumentazioneLinguaggi di programmazioneRustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDartFramework frontend webNext.jsReactVue.js · NuxtSvelteKitAngularFramework serverSpring BootDjangoFastAPIASP.NET CoreNestJS · ExpressFramework per app e desktopTauriFlutterReact NativeElectronAlgoritmiBasi degli algoritmiAlgoritmi fondamentaliAlgoritmi avanzatiAlgoritmi pratici
CommunityProgettiLog di sviluppoPromptProblemi degli strumenti di IAVetrinaGuida alla community
CollaboraTrasferimento tecnicoRealizzazione del sito webRealizzazione di app desktopPipeline di rilascio e pagamentoPartner commercialeContatti
ServiziDesktop remotoPacchetti di installazione su misura
TASTEDEV
Prodotti

Strumenti desktop

TASTECADApri con leggerezza anche i disegni più complessiTASTEFILESSolo i file che servono, alla massima velocitàTASTEFTPLa via più ordinata per i tuoi fileTASTESSHUn legame più solido tra te e i tuoi serverTASTEZIPComprimi più veloce, estrai più sicuro

Strumenti per sviluppatori

TASTECODEModifica, compila, esegui il debug e testa app Rust in un'unica finestraTASTESTUDIODalla modifica ai test remoti e alle correzioni IA approvateTASTEETLSposta i dati guardando i valori

Server

TASTEREMOTEUn desktop remoto che gira sul tuo serverTASTEGEOUn server geospaziale compatibile con GeoServer, ricostruito in RustTASTEMAILRiprendi il controllo della tua posta

Inizia

DownloadUltime versioni di ogni prodottoDocsCome usare ogni prodottoAcquistaAbbonamenti e licenze perpetueTutti i prodottiTutti i prodotti a colpo d’occhio
Tutti i prodotti
MarketplaceNotizie
Tecnologia

Notizie

Notizie di sviluppo di oggiAnnunci ufficiali su linguaggi, framework, GitHub e IADocumentazioneGuide a linguaggi, framework e algoritmi

Linguaggi di programmazione

RustTypeScriptJavaScriptPythonGoC#JavaCC++KotlinDart

Framework

Framework frontend webNext.jsReactVue.js · NuxtSvelteKitAngular
Framework serverSpring BootDjangoFastAPIASP.NET CoreNestJS · Express
Framework per app e desktopTauriFlutterReact NativeElectron

Algoritmi

Basi degli algoritmiAnalisi della complessità · Ordinamento · Ricerca · Strutture dati di base · Alberi e heapAlgoritmi fondamentaliVisita dei grafi · Cammini minimi e alberi ricoprenti · Programmazione dinamica · Algoritmi greedy · Divide et impera · BacktrackingAlgoritmi avanzatiAlgoritmi sulle stringhe · Matematica e teoria dei numeri · Manipolazione dei bit · Alberi di segmenti · Union-FindAlgoritmi praticiStrategia per colloqui di programmazione · Cache LRU · Rate limiting · Hashing consistente
Tutta la documentazione di sviluppo
Community
ProgettiScopri sviluppatori e lavoriLog di sviluppoDecisioni e lezioni appresePromptIstruzioni riutilizzabiliProblemi degli strumenti di IAProblemi e alternative di Claude, Codex, GeminiVetrinaRisultati completatiGuida alla communityCome sviluppiamo in modo aperto
Collabora
Trasferimento tecnicoApp native in Rust ed eguiRealizzazione del sito web10 lingue, account, documentazione e downloadRealizzazione di app desktopRust ed egui, senza WebViewPipeline di rilascio e pagamentoFirma, MSI, deb, rpm, AppImage, hashPartner commercialeConsigliaci e ricevi il 30%ContattiSviluppo, partnership e investimenti
Servizi
Desktop remotoRaggiungi il tuo computer dal browserPacchetti di installazione su misuraSolo il necessario, impostazioni precaricate
Acquista
IT
한국어EnglishDeutschEspañolFrançaisItalianoPortuguês (Brasil)日本語简体中文繁體中文
Accedi
Accedi
TASTEDEV

Dai piccoli strumenti a uno sviluppo migliore.

support@tastedev.netSostieni TASTEDEV
ProdottiGamma di prodottiAcquistaDocsDownloadMarketplaceAssistenza
CommunityProgettiLog di sviluppoPromptProblemi degli strumenti di IAVetrina
NormeInformativa sulla privacyTermini di servizioCondizioni di abbonamentoRimborsiLinee guida della community
AccountAccediRegistrati
Visitatori
Oggi
012345678901234567890123456789012345678901234567890123456789
Ieri
012345678901234567890123456789012345678901234567890123456789
Visualizzazioni totali
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
Società
GXSOFT
Rappresentante
CHOI YOUNG GU
Numero di registrazione
853-44-00368
Indirizzo
9F V24, 351 Gyeongin-ro, Michuhol-gu, Incheon, Republic of Korea
Telefono
+82-10-4404-1523
E-mail
whitecalvin@tastedev.net
Responsabile privacy
CHOI YOUNG GU

© 2026 TASTEDEVLe informazioni sui prodotti si basano su fonti di sviluppo verificate.Rilasciato · in miglioramento

Documentazione di Programmazione dinamica
Programmazione dinamica
ConceptsHow It WorksImplementationComplexityPractice ProblemsReal-World Use
Discussioni

Guida a Programmazione dinamica · 1/6

Concepts

Per ora questo capitolo è disponibile solo in inglese.

Dynamic programming (DP) is a way of solving a problem by breaking it into smaller subproblems, solving each subproblem once, storing the answer, and reusing it whenever the same subproblem comes up again. The name comes from Richard Bellman, who developed the method in the 1950s; "programming" here means planning with a table, not writing code. This chapter explains when DP applies, the two properties that make it work, and the vocabulary used in the rest of the guide.

Two properties that make DP work

A problem is a good fit for DP when it has both of these properties.

  • Overlapping subproblems: a naive recursive solution solves the same subproblem many times. Storing each result turns repeated work into a table lookup.
  • Optimal substructure: an optimal answer for the whole problem can be built from optimal answers to its subproblems. The shortest path from A to C through B contains the shortest path from A to B, for example.

Divide and conquer also splits a problem into subproblems, but in merge sort the halves never overlap, so there is nothing to reuse. Greedy algorithms also rely on optimal substructure, but they commit to one locally best choice at each step; DP instead considers every choice and keeps the best one, which is why it works on problems where greedy fails.

Seeing the overlap: Fibonacci

The Fibonacci numbers are defined by F(0) = 0, F(1) = 1 and F(n) = F(n-1) + F(n-2). Translating the definition directly into code works, but it is extremely slow because the same values are recomputed again and again.

calls = 0


def fib(n: int) -> int:
    global calls
    calls += 1
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)


print(fib(25), calls)  # 75025 242785

Computing F(25) takes almost a quarter of a million calls, and the count grows roughly like 1.6^n. Yet there are only 26 distinct subproblems, F(0) through F(25). That gap between "calls made" and "distinct subproblems" is exactly what DP removes.

Two ways to remember answers

Memoization (top-down) keeps the recursive structure and adds a cache. The first call for a given argument computes the result; later calls return the stored value. In Python, functools.cache does this with one decorator.

from functools import cache


@cache
def fib(n: int) -> int:
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)


print(fib(90))           # 2880067194370816120
print(fib.cache_info())  # CacheInfo(hits=88, misses=91, maxsize=None, currsize=91)

Tabulation (bottom-up) removes recursion entirely. You decide an order in which every subproblem's dependencies are already solved, then fill a table in that order with a loop.

Domande su questo capitolo?
Capitolo successivoHow It Works
def fib(n: int) -> int:
    table = [0] * (n + 1)
    if n > 0:
        table[1] = 1
    for i in range(2, n + 1):
        table[i] = table[i - 1] + table[i - 2]
    return table[n]


print(fib(90))  # 2880067194370816120

Both versions compute each of the n + 1 values once, so both run in O(n) time. Memoization is usually quicker to write and only visits states that are actually reachable. Tabulation avoids recursion depth limits and function call overhead, and it makes space optimizations easier to see.

Vocabulary

TermMeaningFibonacci example
StateThe parameters that identify one subproblemn
Recurrence (transition)How a state's answer is built from smaller statesF(n) = F(n-1) + F(n-2)
Base caseStates answered directly without recursionF(0) = 0, F(1) = 1
Table / memoWhere answers are storedlist table or the @cache dictionary
Order of evaluationThe order in which bottom-up fills the tableincreasing n
AnswerThe state (or combination of states) you returnF(n)

When to reach for DP

Look for DP when a problem asks for one of these and the input is small enough for a table of states to fit in memory.

  • The minimum or maximum of something: fewest coins, cheapest path, largest value in a bag.
  • The number of ways to do something: paths in a grid, ways to climb stairs, ways to decode a string.
  • Whether something is possible at all: can a set be split into two equal sums, can a string be segmented into dictionary words.

A strong hint is a solution that makes a sequence of choices, where after each choice the rest of the problem looks like a smaller copy of the original. If two different sequences of choices can lead to the same remaining problem, you have overlapping subproblems.

Summary

  • DP solves each distinct subproblem once and reuses the stored answer.
  • It needs overlapping subproblems and optimal substructure.
  • Memoization adds a cache to recursion; tabulation fills a table in dependency order.
  • Every DP solution is described by its state, recurrence, base cases, evaluation order and final answer.

0 commenti

Commenti principaliPrima i più recenti

Accedi · Accedi per lasciare un commento.