Podstawy Programowania
Złożoność obliczeniowa
Sumy prefiksowe
Zliczanie kubełkowe
Wyszukiwanie binarne
Skalowanie
Metoda gąsienicy
Zapewne każdy wie, jak wygląda gąsienica. Jest to typ larwy u motyli i błonówek z podrzędu rośliniarek, jedno ze stadiów rozwoju. Charakteryzuje się miękkim ciałem o robakowatym kształcie i metamerii homonomicznej oraz obecnością nieczłonowanych przydatków odwłokowych nazywanych posuwkami.
Co ma gąsienica do rozwiązywania problemów informatycznych? Otóż posiada mocarną umiejętność – pełzanie.
W bardzo wielu zadaniach napotykamy się na potrzebę przetwarzania informacji dla przedziałów, które spełniają dany warunek. Nazwijmy je interesującymi. W tym artykule będą nas obchodzić problemy, w których jeżeli warunek zachodzi dla fragmentu lub to zachodzi również dla
Oznacza to, że dla każdego początku albo żaden fragment nie jest interesujący, albo istnieje taki koniec że wszystkie interesujące przedziały zawierają się w przedziale
W celu rozwiązywania tego typu problemów możemy dla „pełzać” po kolejnych dopóki fragment spełnia dany warunek. Wówczas przetwarzamy informacje dla znalezionych przedziałów i "skracamy się", po czym kontynuujemy poszukiwania dla Zauważmy, że skoro jest interesujące, to możemy wznowić „pełzanie” dalszym końcem od zamiast od Ta optymalizacja zmniejsza koszt czasowy przeglądnięcia wszystkich interecujących przedziałów z do
Dlaczego?
Zastanówmy się, od czego zależy złożoność gąsienicy. Przy założeniach, że przetwarzanie informacji dla znalezionych przedziałów umiemy wykonywać w czasie stałym, liczba wykonanych operacji jest proporcjonalna do sumarycznej liczby "przesunięć" początków i końców. Skoro za każdym razem przesuwamy początek lub koniec o jeden w przód, łącznie każdy z nich przesunie się conajwyżej razy. Łączna liczba przesunięć wyniesie co najwyżej co daje nam maksymalnie operacji. Gdybyśmy chcieli sprawdzać oddzielnie każdy przedział, w sumie musielibyśmy sprawdzić możliwych przedziałów (dla możliwych początków i możliwych końców).
Mając dane i ciąg liczb naturalnych podaj długość najdłuższego przedziału takiego, że
Niech będzie równe sumie liczb na przedziale Dla każdej pozycji szukamy najdłuższego fragmentu zaczynającego się na spełniającego podaną nierówność. Będziemy iterować się po kolejnych tak długo, aż
Wówczas możemy zaktualizować wynik i poszukać najdłuższego fragmentu spełniającego podaną nierówność i zaczynającego się na Jako, że zaczniemy iterację od wcześniej wyliczonego Rozwiązanie znajdziemy w czasie
int najdluzszy_przedzial(int k, int a[]) {
int j = 1, suma = a[1], wynik = 0;
for (int i = 1; i <= n; i ++) {
if (j < i) {
j = i;
suma = a[i];
}
while (j + 1 <= n && suma + a[j + 1] < K) {
suma += a[j + 1];
j ++;
}
wynik = max(wynik, j - i + 1);
suma -= a[i];
}
return wynik;
}