diff --git a/banque.c b/banque.c index 8e4be4f..3b030e6 100644 --- a/banque.c +++ b/banque.c @@ -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;