Stellen Sie die natürliche Zahl als Summe der Quadrate dar, indem Sie die dynamische Programmierung verwenden

8

Das Problem besteht darin, die minimale Anzahl von Quadraten zu finden, die benötigt werden, um zu einer Zahl n zu addieren.

Einige Beispiele:

%Vor%

Ich kenne Lagranges Vier-Quadrate-Theorem , das besagt, dass jede natürliche Zahl dargestellt werden kann als die Summe von vier Quadraten.

Ich versuche das mit DP zu lösen.

Das ist, was ich herausgefunden habe (es ist nicht korrekt)

%Vor%

Was ist der richtige DP-Weg, um das zu lösen?

    
rohit89 19.10.2010, 11:19
quelle

4 Antworten

14

Ich bin mir nicht sicher, ob DP der effizienteste Weg ist, um dieses Problem zu lösen, aber Sie haben nach DP gefragt.

min [i] = min (min [i - 1] + 1, 1 + min [i - prev]) wobei prev eine Quadratzahl & lt; ich
Das ist nahe, ich würde die Bedingung als

schreiben %Vor%

Beachten Sie, dass Sie für jedes i verschiedene mögliche Werte von prev prüfen müssen.

Hier ist eine einfache Implementierung in Java.

%Vor%     
Nikita Rybak 19.10.2010, 11:30
quelle
5

Scheint mir, dass Sie in der Nähe sind ...

Sie nehmen die min () von zwei Begriffen, von denen jeder min[i - p] + 1 ist, wobei p entweder 1 oder irgendein anderes Quadrat & lt; ich.

Um das zu beheben, nehmen Sie einfach min () von min[i - p] + 1 über all p (wobei p ein Quadrat & lt; i ist).

Das wäre ein korrekter Weg. Es kann einen schnelleren Weg geben.

Es kann auch die Lesbarkeit verbessern, wenn Sie min[] und min() verschiedene Namen angeben. : -)

P.S. Der obige Ansatz erfordert, dass Sie min[] entweder explizit oder als Teil Ihres DP-Frameworks memozieren. Andernfalls wäre die Komplexität des Algorithmus aufgrund der Rekursion etwas wie O (sqrt (n)!): - p, obwohl der durchschnittliche Fall viel besser sein könnte.

P. P. S. Siehe @ Nikitas Antwort für eine nette Implementierung. Zu denen würde ich die folgenden Optimierungen hinzufügen ... (Ich bin nicht pingelig seine Implementierung - er präsentierte es als eine einfache.)

  1. Überprüfen Sie, ob n ein perfektes Quadrat ist, bevor Sie in die äußere Schleife eintreten: Wenn ja, ist min [n] = 1 und wir sind fertig.
  2. Überprüfen Sie, ob i ein perfektes Quadrat ist, bevor Sie die innere Schleife betreten: Wenn ja, min [i] = 1, und überspringen Sie die innere Schleife.
  3. Brechen Sie aus der inneren Schleife aus, wenn min [i] auf 2 gesetzt wurde, weil es nicht besser wird (wenn es mit einem Quadrat gemacht werden könnte, wären wir nie in die innere Schleife gegangen, dank der vorherigen Optimierung).
  4. Ich frage mich, ob die Abbruchbedingung auf der inneren Schleife geändert werden kann, um die Anzahl der Iterationen zu reduzieren, z. j*j*2 <= i oder sogar j*j*4 <= i . Ich denke schon, aber ich habe meinen Kopf nicht komplett um mich herum verstanden.
  5. Für großes i wäre es schneller, ein Limit für j vor der inneren Schleife zu berechnen und j direkt mit ihm für die Schleifenbeendigungsbedingung zu vergleichen, anstatt j bei jeder inneren Schleifeniteration zu quadrieren. ZB

    %Vor%

    Auf der anderen Seite brauchen Sie j ^ 2 für den Rekursionsschritt, so lange Sie es speichern, können Sie es genauso gut verwenden.

LarsH 19.10.2010 11:30
quelle
0

Für Abwechslung, hier ist eine andere Antwort:

Definiere minsq [i, j] als die minimale Anzahl von Quadraten von {1 ^ 2, 2 ^ 2, ..., j ^ 2}, die sich zu i addieren. Dann ist die Rekursion:

%Vor%

d. h., um minsq [i, j] zu berechnen, verwenden wir entweder j ^ 2 oder nicht. Unsere Antwort für n ist dann:

%Vor%

Diese Antwort ist vielleicht konzeptionell einfacher als die zuvor präsentierte, aber Code-weise ist es schwieriger, da man mit den Basisfällen vorsichtig sein muss. Die zeitliche Komplexität für beide Antworten ist asymptotisch gleich.

    
sasuki 08.01.2015 17:14
quelle
0

Ich stelle einen verallgemeinerten sehr effizienten dynamischen Programmieralgorithmus vor, um die minimale Anzahl von positiven ganzen Zahlen gegebener Energie zu finden, um ein gegebenes Ziel in JavaScript zu erreichen.

Um zum Beispiel 50000 mit ganzen Zahlen der 4. Potenz zu erreichen, wäre das Ergebnis [10,10,10,10,10] oder 18571 mit ganzen Zahlen der 7. Potenz zu erreichen, würde [3,4] ergeben. Dieser Algorithmus würde sogar mit rationalen Potenzen arbeiten, um 222 mit ganzen Zahlen von zu erreichen, wäre [ 32, 32, 243, 243, 243, 3125 ]

%Vor%
    
Redu 01.03.2017 21:42
quelle

Tags und Links