Разбор задачи Торговля акциями

Слайд 2

Торговля акциями Требуется написать программу, которая по имеющимся данным о стоимости

Торговля акциями

Требуется написать программу, которая по имеющимся данным о стоимости акций

в каждый из дней, найдет оптимальную стратегию покупки и продажи акций.
При этом для простоты будем считать, что за эти n дней купить акции можно не более одного раза и продать акции можно также не
Кроме этого, будем считать, что продажа и покупка будет осуществляться только с акциями одного типа. На начало этого периода вы располагаете суммой в x рублей. Для каждого из дней известна цена ai по которой можно купить одну акцию, и цена bi по которой можно одну акцию продать.
Разрешается продавать и покупать только целое число акций (например, если у вас есть 5 рублей, а акция стоит 2 рубля, то вы можете купить не более двух акций).
Слайд 3

Торговля акциями Входные данные Первая строка входного файла содержит два целых

Торговля акциями

Входные данные
Первая строка входного файла содержит два целых числа

n и x (1 ≤ n ≤ 100000, 1 ≤ x ≤ 106).
Вторая строка входного файла содержит n целых чисел a1, . . . , aт. Третья строка входного файла содержит n целых чисел b1, . . . , bт. Для каждого индекса i (1 ≤ i ≤ n) выполняются неравенства 1 ≤ bi ≤ ai ≤ 1000.
Выходные данные
В первой строке выходного файла выведите максимальную сумму, которой вы можете обладать по окончании рассматриваемого периода. Во второй строке выведите два числа — номер дня d1, в который следует купить акции, и номер дня d2, в который эти акции следует продать (должно выполняться неравенство d2 > d1). При этом подразумевается, что покупается столько акций, сколько их можно купить на x рублей, а потом они все продаются. Если в найденной вами стратегии продавать и покупать акции не требуется, то выведите выведите во второй строке «-1 -1».
Слайд 4

Примеры

Примеры

Слайд 5

Подсказки по синтаксису python Читаем первые 2 числа: n,m = map(int,

Подсказки по синтаксису python

Читаем первые 2 числа:
n,m = map(int, input().split())
Читаем первый

массив:
A = [int(i) for i in input().split()]
Слайд 6

Если у вас падает на тестах №… № 27 Проверьте, не

Если у вас падает на тестах №…

№ 27
Проверьте, не забыли ли

вы прибавить остаток от деления при покупке акций
№ 7
В С++ если вы используете деление двух int, но не приводите к вещественному типу перед делением (к double или float), то 46/33 например, будет равно 46/41. В python с этим проблем не возникает.
Слайд 7

Осторожно, дальше разбор и спойлеры ;)

Осторожно, дальше разбор и спойлеры ;)

Слайд 8

Подводные камни Забыть прибавить к ответу остаток денег от х Жадный

Подводные камни

Забыть прибавить к ответу остаток денег от х
Жадный алгоритм тут

не работает
Перебор – «Превышено максимальное время работы»
Будет ли оптимально умножить максимум цены в продаже на минимум до него в цене покупке? Может, и не будет оптимально? Может, в серединке был вариант получше? Придумайте свой тест на эту ситуацию.
Слайд 9

8 9 2 3 1 3 3 1 61 1 50

8 9    2 3 1   3   3 1 61 1   50  1  

2 3

Как составить тест чтобы сломать свою программу?

То есть, возможно, что продать по самой большой цене - не гарантия самого большого выигрыша

Пример такого теста:

Слайд 10

Алгоритм решения 1. Идём с конца массива b. Запоминаем b_max, если

Алгоритм решения

1. Идём с конца массива b. Запоминаем b_max, если нашли

большее, то начинаем рассматривать как кандидата на ответ
2. Для этого кандидата (обозначим день k, соответственно, рассматриваем b[k]) находим минимум в массиве a, из тех a[i], которые от первого дня до дня k. Запоминаем его день в переменную h. Вычисляем, сколько мы заработаем с этой парой чисел (результирующую функцию) и запоминаем это значение в F_rez_tmp. F_rez_tmp = x/a[h] * b[k]
Если оно оказалось больше, чем F_rez_max, найденное для предыдущих кандидатов, то у нас новая “пара-победитель”.
Перезаписываем F_rez_max, не забываем сохранить где-нибудь значения «победных» дней для покупки и для продажи. Пусть в h_best и k_best
Возвращаемся к пункту 1 и продолжаем просматривать b, пока он не закончится.
Когда он закончится, у нас будет и значение F_rez_max (к которому не забываем прибавить остаток денег от деления) и значения двух дней, в которые следует купить (h_best) и продать (k_best)
Слайд 11

Решение на С++ Автор решения: Дегтярев Иван

Решение на С++

Автор решения: Дегтярев Иван

Слайд 12

Решение на Python Автор решения: Баранов Андрей

Решение на Python

Автор решения: Баранов Андрей