Учитывая массив размером n, содержащий 0 и 1 и две операции, найдите минимальное количество операций, чтобы все элементы были равны 0 - PullRequest
0 голосов
/ 29 декабря 2018

Учитывая массив размером n, содержащий 0 и 1 и две операции, найдите минимальное количество операций, чтобы все элементы были равны 0.

Операции:

  1. Переверните i-й элемент, если (i + 1) -й элемент равен 1 и от (i + 2) -го до всех последовательных элементов равен 0 или не существует (если i + 2 = n).(0 <= i <= n-2) </p>

    Например, вышеуказанная операция применима для:

для этого элемента

|

V   

1100

или

на этом элементе

  |

  V   

1011

Перевернуть n-й элемент без каких-либо ограничений.

n <= 50 </p>

Например, вход: 1,0,0,0

Выход: 15

Объяснение:

1000 -> 1001 -> 1011 -> 1010 -> 1110 -> 1111 -> 1101 -> 1100 -> 0100 -> 0101 -> 0111 -> 0110 ->0010 -> 0011 -> 0001 -> 0000

1 Ответ

0 голосов
/ 30 декабря 2018

Для любого массива, кроме массивов со всеми 0 s, возможны только две операции.Либо переверните n-й элемент, либо переверните элемент прямо перед последним 1 в массиве.
Нам не нужно рассматривать крайний случай только первого элемента, являющегося 1, потому что мы можем добавить любое количество нулейв начало массива, и это не меняет результат, т. е. [1, 0, 0, 0] и [0, 1, 0, 0, 0] требуют одинакового количества минимальных операций, чтобы стать всеми 0 s.
Это означает, что на каждой последовательности 0 и 1 s, одна из операций продвинется на один шаг ближе к 0 s, а другая операция - на один шаг дальше.
Результатом этих наблюдений является то, что у нас фактически есть числовая система, очень похожая на двоичную икаждая операция может рассматриваться как увеличение или уменьшение числа на 1, и это означает, что для каждой последовательности 0 s и 1 s существует эквивалентное двоичное число и десятичное число, которое является числом шагов между этим числом и 0.
Я нашел связь между этой системой и двоичным файлом, которая выглядит следующим образом:
Если мы перебираем массив fОт начала до конца и переворачиваем каждый элемент, который идет после 1, мы получаем эквивалентный двоичный файл.Эта операция должна быть выполнена на месте, это означает, что мы изменяем сам массив во время итерации, и результат каждой итерации влияет на следующую итерацию.У меня нет доказательства того, почему это правильно, может быть, кто-то может предоставить доказательство.

С учетом всего сказанного, сам алгоритм прост.Это в питоне:

a = [1, 0, 0, 0]

# convert to equivalent binary
for i in range(1, len(a)):
    a[i] = int(not a[i]) if a[i-1] == 1 else a[i]

# convert to decimal
bin_str = ''.join(map(str, a))
print(int(bin_str, 2))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...