Dynamische Programmierung (DP) ist ein effizienter Algorithmus, der zur Lösung einiger Probleme mit überlappenden Teilproblemen und optimalen Unterstruktureigenschaften verwendet wird. Es gibt einige Techniken zur Verbesserung der Effizienz bei der Implementierung dynamischer Programmieralgorithmen in der Sprache C++. In diesem Artikel werden der dynamische Programmieralgorithmus und seine Anwendungstechniken in C++ vorgestellt.
Die Hauptidee des dynamischen Programmieralgorithmus besteht darin, das Problem in eine Reihe von Unterproblemen zu zerlegen und bei der Lösung jedes Unterproblems einen Zustand beizubehalten und diesen Zustand zu verwenden, um wiederholte Berechnungen zu vermeiden. Der dynamische Programmieralgorithmus kann einige rechenintensive Probleme lösen, da er jedes Teilproblem nur einmal und nicht jedes Mal berechnen muss.
Der dynamische Programmieralgorithmus muss drei Elemente erfüllen:
(1) Optimale Unterstruktur: Die optimale Lösung eines Problems enthält die optimale Lösung seiner Unterprobleme.
(2) Keine Nachwirkungen: Alle Zustände im Prozess beziehen sich nur auf den aktuellen Zustand und haben nichts mit dem vorherigen Zustand zu tun.
(3) Überlappende Teilprobleme: Mehrere Teilprobleme überlappen sich, um wiederholte Berechnungen zu vermeiden.
Es gibt zwei grundlegende Klassifizierungen der dynamischen Programmierung: eine ist zustandsbasierte dynamische Programmierung und die andere ist entscheidungsbasierte dynamische Programmierung. Unter zustandsbasierter dynamischer Programmierung versteht man das Speichern der Lösungen für jedes Unterproblem während der Berechnung und das anschließende Berechnen der Lösung für das größere Problem basierend auf den Werten dieser Lösungen. Der Zustand wird normalerweise mithilfe einer Datenstruktur, beispielsweise einem Array, gespeichert. Entscheidungsbasierte dynamische Programmierung bezieht sich auf die Bestimmung der optimalen Lösung für das größere Problem basierend auf der optimalen Lösung jedes Teilproblems während der Berechnung. Diese Methode wird häufig zur Lösung von Optimierungsproblemen oder bei der Berechnung des Minimalwerts verwendet.
Bei der Implementierung dynamischer Programmieralgorithmen in C++ gibt es einige Anwendungsfähigkeiten, die die Effizienz verbessern können. Zu diesen Techniken gehören:
(1) Verwenden Sie Konstanten anstelle von Array-Indizes: Bei einigen dynamischen Programmierproblemen sind mehrere Zugriffe auf das Array erforderlich. Zu diesem Zeitpunkt können Sie den Index des Arrays durch eine Konstante ersetzen, was den Zugriff beschleunigen kann. Beispiel:
for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ dp[i][j] = max(dp[i-1][j],dp[i][j-1])+1; } }
Sie können die Variable k verwenden, um den Index des dp-Arrays zu ersetzen:
for(int k=2;k<=n+m;k++){ for(int i=1;i<=n;i++){ int j = k-i; if(j<1 || j>m) continue; dp[i][j] = max(dp[i-1][j],dp[i][j-1])+1; } }
(2) Optimieren des Arrays: Bei einigen dynamischen Programmierproblemen ist die Größe des Arrays sehr groß, was zu Speicherbeschränkungen führen kann . Zu diesem Zeitpunkt können Sie ein rollierendes Array oder die erste Dimension eines zweidimensionalen Arrays verwenden, um die Zwischenergebnisse zu speichern. Zum Beispiel:
int dp[N][M]; for(int i=0;i<N;i++){ for(int j=0;j<M;j++){ dp[i][j] = max(dp[i-1][j],dp[i][j-1])+1; } }
kann optimiert werden zu:
int dp[2][M]; for(int i=0;i<N;i++){ int cur = i%2, pre = (i+1)%2; for(int j=0;j<M;j++){ dp[cur][j] = max(dp[pre][j],dp[cur][j-1])+1; } }
(3) Platzersparnis: Bei einigen dynamischen Programmierproblemen müssen nur die neuesten Zustände anstelle des gesamten Arrays gespeichert werden. An dieser Stelle können Sie ein Scroll-Array verwenden, um nur die neuesten Zustände zu speichern.
(4) Vermeiden Sie wiederholte Berechnungen: Bei einigen dynamischen Programmierproblemen kann es zu wiederholten Unterproblemen kommen. Zu diesem Zeitpunkt können Sie die gespeicherte Suche oder die dynamische Programmierung von unten nach oben verwenden, um wiederholte Berechnungen zu vermeiden.
Im Folgenden sind einige Beispiele für dynamische Programmierprobleme aufgeführt:
(1) Fibonacci-Folge: Die Fibonacci-Folge bedeutet, dass beginnend bei 0 und 1 jede Zahl gleich den beiden vorherigen ist. Die Summe der Zahlen. Zum Beispiel 0, 1, 1, 2, 3, 5, 8, 13, 21.
Die Rekursionsformel lautet: f[n] = f[n-1] + f[n-2]
Mit dem dynamischen Programmieralgorithmus kann sie wie folgt realisiert werden:
int dp[N]; dp[0] = 0; dp[1] = 1; for(int i=2;i<=n;i++){ dp[i] = dp[i-1] + dp[i-2]; }
(2) Rucksackproblem: Das Das Rucksackproblem bedeutet, dass es N Artikel gibt, von denen jeder ein Gewicht und einen Wert hat. Ermitteln Sie anhand der Kapazität C eines Rucksacks den maximalen Wert, der geladen werden kann, ohne die Kapazität des Rucksacks zu überschreiten.
Mit dem dynamischen Programmieralgorithmus können Sie Folgendes erreichen:
int dp[N][C]; for(int i=0;i<N;i++){ for(int j=0;j<C;j++){ dp[i][j] = 0; } } for(int i=0;i<N;i++){ for(int j=0;j<=C;j++){ if(j>=w[i]){ dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]); } else{ dp[i][j] = dp[i-1][j]; } } }
Das Obige ist eine kurze Einführung in den dynamischen Programmieralgorithmus und seine Anwendungstechniken in C++. Bei komplexen dynamischen Programmierproblemen müssen auch Zeitkomplexität und Raumkomplexität berücksichtigt werden. Daher müssen bei der Implementierung eines dynamischen Programmieralgorithmus verschiedene Faktoren berücksichtigt und eine geeignete Methode ausgewählt werden.
Das obige ist der detaillierte Inhalt vonDynamischer Programmieralgorithmus in C++ und seine Anwendungskenntnisse. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!