Представьте, что в строке находятся n человек, каждый из которых имеет уникальное для себя значение от 1 до n, мы пытаемся отсортировать их следующим образом:
repeat
swapped = false
for i from 1 to n do:
if a[i] > a[i+1] then
add a friendship between a[i] and a[i+1]
swap(a[i], a[i+1])
swapped = true
end if
end for
until not swapped
Как видите, при каждом обмене между ними происходит дружба, а для человека, если его не поменяли с другим человеком, никакой дружбы между ними не будет, вопрос в том, после того, как операция будет сделана для вводите, какое максимальное количество людей не в друзьях?! Пример ввода:
3
3 1 2
Пример вывода:
2
Я попытался решить эту проблему, используя этот код:
n = int(input())
permutation = list(map(int, input().split()))
dp = [[] for _ in range(n)]
max_length = 0
for i in range(n):
dp[i].append(i)
for j in range(i):
if permutation[j] < permutation[i]:
addable = True
for k in dp[j]:
if (permutation[k] > permutation[i] and k < i) or (permutation[k] < permutation[i] and k > i):
addable = False
break
if addable and len(dp[j]) + 1 > len(dp[i]):
dp[i] = dp[j].copy()
dp[i].append(i)
if len(dp[i]) > max_length:
max_length = len(dp[i])
print(max_length)
который отлично работает для всех входных данных и дает нам правильный ответ, как я проверил, но имеет временную сложность O(n^3), что совершенно не подходит для больших входных данных. Есть ли способ оптимизировать этот код?! Или хотя бы есть другое решение и подход к этому?! Этот код предполагает, что при каждой замене ребро из полного графа с n вершинами удаляется, и с учетом этого ребра между двумя индексами перестановки будут тогда и только тогда, когда индекс, который выше другого, имеет более высокое значение. .
Вы словно считаете количество инверсий (то есть пар (x, y) таких, что x < y и a[x] > a[y]). Если это так, то это делается за O(n*log(n)): вы сортируете массив с помощью своего любимого алгоритма, подсчитывая количество инверсий, которые вы отменяете на каждом шаге. См. stackoverflow.com/questions/337664/….
Почему ответ 2 для образца ввода? После сортировки осталась только 1 пара людей, которые не стали друзьями.
Ваш вопрос был бы более понятен, если бы вы вначале изложили его словами, без ссылки на код (включая, например, объяснение того, как определяется, являются ли два человека друзьями), а затем привели свой(е) пример(ы) для иллюстрации, затем (и только тогда) представьте код, который вы пробовали, и объясните, почему его нет.
@nocomment Итак, чтобы было ясно: два человека становятся друзьями после завершения операции, если и только если они меняются местами в процессе сортировки, при этом, когда мы пытаемся отсортировать их с помощью заданного алгоритма, между некоторыми людьми возникает некоторая дружба. (Чтобы внести ясность, вы можете считать, что у каждого из них есть имя, и их имя с самого начала является их индексом). Для данного примера при выполнении алгоритма 3 и 1 поменяются местами, и они станут друзьями, после чего очередь будет выглядеть так: 1 3 2 после 3 и 2 очередь отсортирована и 1 2 не друзья.






Таким образом, проблема фактически решена, если мы попытаемся найти самое длинное возрастающее последующее (LIS), при этом нам вообще не нужно выполнять алгоритм. Код ответа на вопрос будет примерно таким:
n = int(input())
permutation = list(map(int, input().split()))
dp = []
for i in range(n):
low, high = 0, len(dp)
while low < high:
mid = (low + high) // 2
if dp[mid] < permutation[i]:
low = mid + 1
else:
high = mid
if low == len(dp):
dp.append(permutation[i])
else:
dp[low] = permutation[i]
print(len(dp))
Если кратко описать этот код, он перебирает элементы и создает массив с учетом порядка элементов в исходном массиве, который увеличивается, и он станет самым длинным, потому что мы рассматриваем каждый элемент и модифицируем dp. массив (который будет массивом самого длинного возрастающего последующего) соответственно. Нашим ответом будет длина массива dp.
Что именно означает «максимальное количество людей, которые не являются друзьями»?