А. Ярмарка оружия [реализация, математика]
Необходимо последовательно сравнить силы наборов, если текущая сила строго больше максимальной предыдущей, то обновляем максимальную и индекс лучшего набора. Вычислить силу набора можно было в нецелых числах как (сумма si, j / wi), или сохранить числитель и знаменатель дроби (sumsmax и wmax) и сравнивая с текущим набором домножить обе части на (wmax·wi). Не стоит забывать, что суммирование 105 чисел до 109 приведёт к переполнению типа integer.
Асимптотика: O(n·max(wi))
B. Имённо-фамильный никнейм [перебор, строки]
Любое решение сводится к тому, чтобы максимизировать подстроку в n (ведь чем больше символов мы возьмём из n, тем меньше потребуется из f).
Обозначим длину такой подстроки за k.
1) Наивное решение может проверять все подстроки строки n для поиска максимального k, после чего искать недостающий конец строки в f. Это будет работать за O(q * |n|2 + q * |f|) в теории, однако лишь в худшем частном случае, когда множество раз наблюдается значительное совпадение подстроки с первой часть строки si (пример: n = " ", f = " ", и все si = " ").
2) Подсчитать все возможные подстроки для n за |n|2, сложить в set или бор, или подсчитать хеши (это будет работать аналогично set). Теперь для каждого si можно последовательно искать k, после чего можно пройтись последовательно по f, узнав, есть ли там оставшиеся |si| - k символов. При использовании set или хешей можно также искать k бинарным поиском, укорачивая или удлиняя текущую строку до длины M на каждой итерации и ища ей соответствие в подстроках n.
Асимптотики такого решения: - Для хешей или set: - если искать k последовательно: O(q * k * log2(|n|2) + q * |f|) - бинарным поиском: O(q * log2(k) * log2(|n|2) + q * |f|) - Для бора: O(q * k + q * |f|)
Код с set, бинарный поиск по k
2) Развернём n, f, и si задом наперёд. Тогда нам нужно максимизировать не подстроку, а подпоследовательность в f, в этом единственное отличие от предыдущего варианта. Искать k для подпоследовательности можно только последовательно, после чего нам нужно найти в n подстроку длины |n| - k, для чего опять же следует предподсчитать все возможные подстроки для n за |n|2 и сложить их в какую-нибудь структуру. Асимптотика решения: \begin{itemize} \item Для хеша или set: O(q * k + q * log2(|n|2)) \item Для бора: O(q * k + q * |n|) \end{itemize}