Skip to content

Commit 5b7f090

Browse files
author
Dimitris Los
committed
Small corrections
1 parent 3fc79d9 commit 5b7f090

File tree

2 files changed

+9
-6
lines changed

2 files changed

+9
-6
lines changed

_includes/source_code/code/37-PDP/mergegame/mergegame_n2.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ int main() {
1717
fscanf(fi, "%ld", &A[i]);
1818
smallest = std::min(smallest, A[i]);
1919
}
20+
fclose(fi);
2021

2122
long j = N;
2223
// Σε κάθε γύρο βρίσκουμε το μικρότερο στοιχείο smallest.

contests/_37-PDP/b-mergegame-solution.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ codename: mergegame
77

88
Μας δίνεται ένας πίνακας $$N$$ στοιχείων και σε κάθε βήμα μπορούμε είτε να διαγράψουμε ένα στοιχείο είτε να συγχωνεύσουμε δύο ίδια στοιχεία $$\texttt{x x}$$ σε ένα: το $$\texttt{x+1}$$. Σκοπός είναι να μεγιστοποιήσουμε την τιμή του τελευταίου στοιχείου.
99

10-
## Λύση σε $$\mathcal{O}(N^2)$$
10+
## Λύση σε $$\mathcal{O}(N^2)$$ χρόνο
1111

1212
Θα ξεκινήσουμε με έναν αλγόριθμο που σε κάθε γύρο, κάνει δύο ειδών κινήσεις που περιλαμβάνουν το μικρότερο στοιχείο $$\texttt{y}$$ του πίνακα:
1313
- **Κίνηση 1η:** Αν έχουμε $$\texttt{x y z}$$ με $$\texttt{x} \neq \texttt{y} \neq \texttt{z}$$, τότε διαγράφουμε το $$\texttt{y}$$.
@@ -28,7 +28,7 @@ $$
2828

2929
Διαισθητικά, ο λόγος που μπορούμε να κάνουμε τις κινήσεις του πρώτου είδους είναι ότι για να συγχωνεύσουμε το $$\texttt{y}$$, θα πρέπει να διαγράψουμε το $$\texttt{z}$$ ή το $$\texttt{x}$$ (ή μία μεγαλύτερη τιμή που έχει προκύψει από συγχώνευσή τους). Αλλά δεν μας συμφέρει να διαγράψουμε μία μεγαλύτερη τιμή και να κρατήσουμε μία μικρότερη.
3030

31-
Για τις κινήσεις του δεύτερου είδους, από την παραπάνω αιτιολόγηση δεν μας συμφέρει να δημιουργήσουμε τριάδες της μορφής $$\texttt{y+1 y y+1}$$, γιατί το $$\texttt{y}$$ θα διαγραφεί. Επομένως, μεγιστοποιούμε το πλήθος των $$\texttt{y+1}$$ και αν κάποια είναι περιττά θα αφαιρεθούν στους επόμενους γύρους.
31+
Για τις κινήσεις του δεύτερου είδους, από την παραπάνω αιτιολόγηση δεν μας συμφέρει να δημιουργήσουμε τριάδες της μορφής $$\texttt{y+1 y y+1}$$, γιατί το $$\texttt{y}$$ θα διαγραφεί. Επομένως, μεγιστοποιούμε το πλήθος των $$\texttt{y+1}$$ και αν κάποια από αυτά είναι περιττά θα αφαιρεθούν στους επόμενους γύρους.
3232

3333
Πηγαίνοντας από τα αριστερά προς τα δεξιά μπορούμε να υλοποιήσουμε τις κινήσεις ενός γύρου σε γραμμικό χρόνο. Επίσης μπορούμε να χρησιμοποιώντας τον ίδιο πίνακα, καθώς το μέγεθος του μικραίνει, άρα αν έχουμε δυο δείκτες στον πίνακα αυτό, έναν για την ανάγνωση και ένα για την εγγραφή, δεν θα επικαλυφθούν. Αφού σε κάθε γύρο, φεύγει τουλάχιστον ένα στοιχείο, μπορεί να υπάρχουν το πολύ $$N - 1$$ γύροι. Άρα συνολικά ο αλγόριθμος χρειάζεται $$\mathcal{O}(N^2)$$ χρόνο.
3434

@@ -38,7 +38,7 @@ $$
3838

3939
**Σημείωση:** Η μεγαλύτερη τιμή μπορεί να αυξηθεί το πολύ κατά $$\log_2 N + 1$$, επομένως οι τιμές χωράνε σε ``long``.
4040

41-
## Βέλτιστη λύση
41+
## Βέλτιστη λύση σε $$\mathcal{O}(N)$$ χρόνο
4242

4343
Για την βέλτιστη λύση, θα κρατάμε την ακολουθία σε φθίνουσα σειρά και θα προσθέτουμε τα στοιχεία ένα ένα από τα αριστερά προς τα δεξιά. Για κάθε στοιχείο που προσθέτουμε, θα αφαιρούμε όλα τα μικρότερα στοιχεία στα δεξιά της υπάρχουσας ακολουθίας. Έπειτα, όσο υπάρχουν ίσα στοιχεία θα κάνουμε συγχωνεύσεις. Με αυτόν τον τρόπο διατηρείται η μονοτονία της ακολουθίας.
4444

@@ -55,15 +55,17 @@ $$
5555
& \texttt{ 3 } \to \\
5656
& \texttt{ 3 {\color{seagreen}{0}} } \to \\
5757
& \texttt{ 3 0 {\color{seagreen}{0}} } \to \\
58-
& \texttt{ 3 0 } \to \\
58+
& \texttt{ 3 1 } \to \\
5959
& \texttt{ 3 1 {\color{seagreen}{3}} } \to \\
6060
& \texttt{ 3 3 } \to \\
6161
& \texttt{ 4 }.
6262
\end{aligned}$$
6363

64-
Ο λόγος που λειτουργεί η μέθοδος αυτή είναι μία γενίκευση της αιτιολόγησης για την πρώτη λύση. Αν έχουμε $$\texttt{x} > \texttt{y} < \texttt{z}$$, τότε το $$\texttt{y}$$ δεν μας συμφέρει να χρησιμοποιηθεί γιατί πρώτα θα πρέπει να διαγραφεί ένα από τα γειτονικά του στοιχεία που είναι μεγαλύτερα. Επίσης με τον τρόπο που γίνονται οι συγχωνεύσεις, πάλι κάνουμε το μέγιστο πλήθος από αυτές.
64+
Διαισθητικά, ο λόγος που αυτή η μέθοδος δουλεύει είναι παρόμοιος με τον λόγο της πρώτης μεθόδου.
65+
* Αν έχουμε $$\texttt{x} > \texttt{y} < \texttt{z}$$, τότε το $$\texttt{y}$$ δεν μας συμφέρει να χρησιμοποιηθεί γιατί πρώτα θα πρέπει να διαγραφεί ένα από τα γειτονικά του στοιχεία που είναι μεγαλύτερα.
66+
* Για τις συγχωνεύσεις που γίνονται, καθώς τις κάνουμε από αριστερά προς τα δεξιά, πάλι θα κάνουμε το μέγιστο πλήθος από αυτές .
6567

66-
Η παρακάτω υλοποίηση κρατάει την ακολουθία σε μία στοίβα. Κάθε στοιχείο θα μπει και θα βγει το πολύ μία φορά. Επομένως, ο αλγόριθμος χρειάζεται $$\mathcal{O}(N)$$ χρόνο και περνάει όλα τα testcases.
68+
Η παρακάτω υλοποίηση κρατάει την ακολουθία σε μία στοίβα. Κάθε στοιχείο θα μπει και θα βγει το πολύ μία φορά από την στοίβα. Επομένως, ο αλγόριθμος χρειάζεται $$\mathcal{O}(N)$$ χρόνο και περνάει όλα τα testcases.
6769

6870
{% include code.md solution_name='mergegame_stack.cc' %}
6971

0 commit comments

Comments
 (0)