наибольший отрезок

[Условие задачи](в сике взял что-то (TODO))

Условие

Вам дан массив длины до из элементов из диапазона . Найдите максимального длину отрезка массива все элементы которого не меньше .

Решение

Решение

Решение в лоб

Можно написать два цикла для перебора границы отрезка, а затем проверить третьим циклом все элементы в отрезке, но это будет .

int ans = 0;
for (int l = 0; l < n; l++) {
  for (int r = l; r < n; r++) {
    bool ok = true;
    for (int i = l; i <= r; i++) {
      if (a[i] < 0) {
        ok = false;
        break;
      }
    }
    if (ok) {
      ans = max(ans, (r - l) + 1);
    }
  }
}

Можно чуть проще и быстрее, проверку отрезка делать параллельно.

Для этого достаточно понять, что в коде выше во втором цикле когда мы увеличиваем правую границу, то можно сразу проверить отрезок за .

Напишем такой код :

int ans = 0;
for (int l = 0; l < n; l++) {
  bool ok = true;
  for (int r = l; r < n; r++) {
    // ...
  }
}
cout << ans;

Подумайте немного, что можно сказать про отрезок , если мы уже знаем ответ для . Аналогично предыдущей задачи про сумму факториалов.

Достаточно посмотреть на a[r] и если он не подходит, никакие отрезки с нашей левой границей и правой границей правей нашей не будет подходить.

int ans = 0;
for (int l = 0; l < n; l++) {
  bool ok = true;
  for (int r = l; r < n; r++) {
    if (a[r] < 0) {
      ok = false;
    }
    if (ok) {
      ans = max(ans, (r - l) + 1);
    }
  }
}
cout << ans;

Асимптотика решения .

Быстрое решение

Продолжим идею решения выше. Когда a[r] < 0, можно сделать break, так-же можно заметить, что если a[r] < 0, то все отрезки с левой границей меньше r можно не рассматривать, так как они тоже закончатся в r.

Такой подход называется два указателя. Первый указатель указывает на начало текущего отрезка, а второй на конец. Вы всего-лишь поддерживаете их в валидном состояние увеличивая в цикле.

int ans = 0;
for (int l = 0; l < n; l++) {
  bool ok = true;
  for (int r = l; r < n; r++) {
    if (a[r] < 0) {
      ok = false;
      l = r;
      break;
    }
    if (ok) {
      ans = max(ans, (r - l) + 1);
    }
  }
}
cout << ans;

Асимптотика решения .

Last change: 2023-10-13, commit: d9af9f8