Рассмотрим эту более простую задачу:
Учитывая вектор размера N, содержащий только значения 1 и 0, найдите подпоследовательность, которая содержит ровно k значений 1.
Пусть A
будет заданным вектором, а S[i] = A[1] + A[2] + A[3] + ... + A[i]
, что означает, сколько единиц в подпоследовательности A[1..i]
.
Для каждого i
мы заинтересованы в существовании j <= i
такой, что S[i] - S[j-1] == k
.
Мы можем найти это в O(n)
с помощью хеш-таблицы, используя следующее соотношение:
S[i] - S[j-1] == k => S[j-1] = S[i] - k
let H = an empty hash table
for i = 1 to N do
if H.Contains (S[i] - k) then your sequence ends at i
else
H.Add(S[i])
Теперь мы можем использовать это для решения вашейзаданная проблема в O(N^3)
: для каждой последовательности строк в заданной матрице (имеется O(N^2)
последовательностей строк), рассмотрите эту последовательность для представления вектора и примените к ней предыдущий алгоритм.Вычисление S
немного сложнее в матричном случае, но это не так сложно понять.Дайте мне знать, если вам нужна дополнительная информация.
Обновление: Вот как алгоритм будет работать на следующей матрице, предполагая k = 12
:
0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0
Рассмотримтолько первая строка:
0 1 1 1 1 0
Считайте, что это вектор 0 1 1 1 1 0
и примените к нему алгоритм для более простой задачи: мы обнаружим, что подпоследовательности не добавляется до 12, поэтому мы идем дальше.
Рассмотрим первые две строки:
0 1 1 1 1 0
0 1 1 1 1 0
Считайте их вектором 0+0 1+1 1+1 1+1 1+1 0+0 = 0 2 2 2 2 0
и примените к нему алгоритм для более простой задачи: опять же, нет подпоследовательности, которая складывается до 12,поэтому идем дальше.
Рассмотрим первые три строки:
0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0
Считаем их вектором 0 3 3 3 3 0
и применим алгоритм к более простой задаче: мы находим последовательность, начинающуюсяв положении 2 и заканчивая в положении 5, чтобы быть решением.Отсюда мы можем получить весь прямоугольник с простой бухгалтерией.