forked from menault/2026_TD3_DEV51_Qualite_Algo
F5 : meilleure période en un seul parcours (O(J³) → O(J))
La triple boucle recalculait la somme de chaque période (i, j) : J(J+1)(J+2)/6 = 167 millions d'additions pour 1 000 jours. Avec les sommes préfixes, la meilleure période finissant au jour j commence juste après le plus petit préfixe vu jusque-là : un seul parcours suffit. En gardant le premier minimum et en ne remplaçant le meilleur que s'il est strictement dépassé, on retrouve la même période que l'original en cas d'égalité (vérifié sur 200 000 tableaux aléatoires). Temps (-O2) : 0,25 s → 0,10 s. Empreinte inchangée (ff68d260a7a58441). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -127,21 +127,28 @@ void total_par_jour(const Transaction *t, int n, long *totaux)
|
||||
}
|
||||
|
||||
/* F5 : période de jours consécutifs dont la somme des soldes est maximale */
|
||||
/* Avec prefixe(j) = totaux[0] + ... + totaux[j-1], la somme des jours i à j
|
||||
* vaut prefixe(j+1) - prefixe(i). Pour chaque fin j, le meilleur début est
|
||||
* donc l'indice du plus petit prefixe(i), i <= j. On garde le premier minimum
|
||||
* et on ne remplace le meilleur que s'il est strictement dépassé : on obtient
|
||||
* la même période que la triple boucle d'origine, même en cas d'égalité. */
|
||||
long meilleure_periode(const long *totaux, int nb_jours, int *debut, int *fin)
|
||||
{
|
||||
long meilleur = totaux[0];
|
||||
long prefixe = 0, prefixe_min = 0;
|
||||
int debut_min = 0;
|
||||
*debut = 0;
|
||||
*fin = 0;
|
||||
for (int i = 0; i < nb_jours; i++) {
|
||||
for (int j = i; j < nb_jours; j++) {
|
||||
long somme = 0;
|
||||
for (int k = i; k <= j; k++)
|
||||
somme += totaux[k];
|
||||
if (somme > meilleur) {
|
||||
meilleur = somme;
|
||||
*debut = i;
|
||||
*fin = j;
|
||||
}
|
||||
for (int j = 0; j < nb_jours; j++) {
|
||||
if (prefixe < prefixe_min) { /* prefixe vaut ici prefixe(j) */
|
||||
prefixe_min = prefixe;
|
||||
debut_min = j;
|
||||
}
|
||||
prefixe += totaux[j]; /* prefixe vaut maintenant prefixe(j+1) */
|
||||
if (prefixe - prefixe_min > meilleur) {
|
||||
meilleur = prefixe - prefixe_min;
|
||||
*debut = debut_min;
|
||||
*fin = j;
|
||||
}
|
||||
}
|
||||
return meilleur;
|
||||
|
||||
Reference in New Issue
Block a user