Clasa a IX-a · Frecvență, sume parțiale și ciurul lui EratosteneRead in English
Secvența de sumă maximă (algoritmul lui Kadane) în C++
În engleză: Maximum subarray sum (Kadane's algorithm)
Ideea
Parcurgem vectorul și păstrăm suma secvenței curente, care se termină la poziția i. Dacă suma de până acum a devenit negativă, nu ne mai ajută: începem o secvență nouă chiar de la i. După fiecare pas comparăm suma curentă cu cea mai bună de până acum. Se afișează suma maximă, apoi pozițiile de început și de sfârșit (prima găsită). Funcționează și când toate numerele sunt negative.
Descrierea în engleză
We go through the array and keep the sum of the current subarray, which ends at position i. If the sum so far has become negative, it no longer helps: we start a new subarray right at i. After every step we compare the current sum with the best one so far. The maximum sum is printed, then the start and end positions (the first one found). It also works when all numbers are negative.
- Complexitate
- O(n)
- Clasa
- Clasa a IX-a (Grade 9)
Exemple
Intrare
8 -2 1 -3 4 -1 2 1 -5
Ieșire așteptată
6 4 7
Intrare
3 -5 -2 -8
Ieșire așteptată
-2 2 2
Codul C++
Codul complet, cu comentarii în română. Îl poți modifica liber și îl poți reseta oricând.
/*
* Titlu: Secvența de sumă maximă (algoritmul lui Kadane)
* Clasa: 9
* Capitol: Frecvență, sume parțiale și ciurul lui Eratostene
* Descriere: Parcurgem vectorul și păstrăm suma secvenței curente, care se
* termină la poziția i. Dacă suma de până acum a devenit negativă, nu
* ne mai ajută: începem o secvență nouă chiar de la i. După fiecare
* pas comparăm suma curentă cu cea mai bună de până acum. Se afișează
* suma maximă, apoi pozițiile de început și de sfârșit (prima găsită).
* Funcționează și când toate numerele sunt negative.
* Complexitate: O(n)
*
* Exemplu
* Intrare:
* 8
* -2 1 -3 4 -1 2 1 -5
* Ieșire:
* 6
* 4 7
*
* Exemplu
* Intrare:
* 3
* -5 -2 -8
* Ieșire:
* -2
* 2 2
*/
#include <iostream>
using namespace std;
int v[100001];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> v[i];
}
long long suma = 0, sumaMax = v[1];
int inceput = 1, stMax = 1, drMax = 1;
for (int i = 1; i <= n; i++)
{
if (suma < 0)
{
suma = 0;
inceput = i;
}
suma = suma + v[i];
if (suma > sumaMax)
{
sumaMax = suma;
stMax = inceput;
drMax = i;
}
}
cout << sumaMax << '\n' << stMax << ' ' << drMax << '\n';
return 0;
}
Rulează pe un g++ adevărat (C++17, -O2) prin Compiler Explorer. Programele trebuie să se termine repede: există o limită de timp.