Торговля акциями
В настоящее время на бирже при торговле акциями активно применяются компьютерные системы, которые упрощают и автоматизируют процесс покупки и продажи акций. Некоторые из них даже позволяют вести торговлю вообще без участия человека.
Разумеется, основным критерием, по которому такие системы оцениваются, является прибыль, которую приносит торговля с их применением. Для того, чтобы ее повысить при построении этих систем применяются различные математические методы и модели.
Основной трудностью при создании таких систем является то, что они должны некоторым образом учитывать изменение стоимости акций в будущем, а также его прогнозировать. Ваша задача несколько проще — курсы продажи и покупки акций за весь период из N дней уже известны, необходимо лишь разработать оптимальную стратегию продаж и покупок. При этом для простоты будем считать, что за эти N дней купить акции можно не более одного раза и продать акции можно также не более одного раза.
Кроме этого, будем считать, что продажа и покупка будет осуществляться только с акциями одного типа. На начало этого периода вы располагаете суммой в X рублей. Для каждого из дней известна цена ai (от ask — цена предложения), по которой можно купить одну акцию, и цена bi, по которой можно одну акцию продать. При этом в соответствии с действующими правилами торгов на бирже разрешается продавать и покупать только целое число акций (например, если у вас есть 5 рублей, а акция стоит 2 рубля, то вы можете купить не более двух акций). Требуется написать программу, которая по имеющимся данным о стоимости акций в каждый из дней, найдет оптимальную стратегию покупки и продажи акций.
Входные данные
Первая строка содержит два целых числа N и X (1 ≤ N ≤ 100 000,1 ≤ X ≤ 10^6). Вторая строка содержит N целых чисел a1, ..., aN. Третья строка содержит N целых чисел b1, ..., bN(1 ≤ bi ≤ ai ≤ 1 000).
Выходные данные
В первой строке выведите максимальную сумму, которой вы можете обладать по окончании рассматриваемого периода. Во второй строке выведите два числа — номер дня d1, в который следует купить акции, и номер дня d2, в который эти акции следует продать (должно выполняться неравенство d2 > d1). При этом подразумевается, что покупается столько акций, сколько их можно купить на X рублей, а потом они все продаются. Если в найденной вами стратегии продавать и покупать акции не требуется, то выведите во второй строке "−1 −1". Если существует несколько вариантов оптимальной стратегии, то выведите любой из них.
Примеры
Ввод
5 1000
2 3 1 4 3
1 2 1 2 3
Вывод
3000
3 5
Ввод
5 1000
10 9 8 7 6
9 8 7 6 5
Вывод
1000
-1 -1
Мой код не проходит по времени. Помогите, пожалуйста.
n, x = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
top = x
top_buy = -1
top_sell = -1
m = 0
for i in range(n):
h = x // a[i]
o = x % a[i]
if top_sell < i + 1:
c = b[i:]
m = max(c)
top_sell_new = c.index(m) + i + 1
if m * h + o > top:
top = m * h + o
top_buy = i + 1
top_sell = top_sell_new
print(top)
print(top_buy, top_sell)
Python
Торговля акциями. Линейные алгоритмы. Python.
Вот еще вариант:
https://pastebin.com/iCRBC5RY
Задача №1253. Торговля акциями
##s1 = '5 1000'
##s2 = '10 9 8 7 6'
##s3 = '9 8 7 6 5'
##s2 = '2 3 1 4 3'
##s3 = '1 2 1 2 3'
s1 = input()
s2 = input()
s3 = input()
n, x = map(int, s1.split())
A = list(map(int, s2.split()))
B = list(map(int, s3.split()))
# Вспомогательный список
# B[i][0] - масимальная цена продажи в этот день и позже
# B[i][1] - индекс дня с максимальной ценой продажи
B[-1] = (B[-1], -1)
for i in range(2,len(B)):
~~~~if B[-i] > B[-i+1][0]:
~~~~~~~~B[-i] = (B[-i], -i)
~~~~else:
~~~~~~~~B[-i] = B[-i+1]
a_mn = A[0]# минимальная цена покупки не позже текущего дня
a_mni = 0# индекс для с минимальной ценой покупки
mx = x# максимальные деньги после покупки-продажи
mx_ij = (-1,-1)# дни покупки и продажи, нумерация с 1
for i in range(len(A)-1):# -1 потому, что покупать в последний день нельзя
~~~~if A[i] < a_mn:
~~~~~~~~a_mn = A[i]
~~~~~~~~a_mni = i
~~~~n_buy = x // a_mn# число купленных
~~~~rest = x % a_mn# сдача
~~~~x_sell = n_buy * B[i+1][0] + rest# деньги после продажи в этот день
~~~~if x_sell > mx:
~~~~~~~~mx = x_sell
~~~~~~~~mx_ij = (i+1, len(B) + B[i+1][1] +1)
print(mx)
print(*mx_ij)
https://pastebin.com/iCRBC5RY
Задача №1253. Торговля акциями
##s1 = '5 1000'
##s2 = '10 9 8 7 6'
##s3 = '9 8 7 6 5'
##s2 = '2 3 1 4 3'
##s3 = '1 2 1 2 3'
s1 = input()
s2 = input()
s3 = input()
n, x = map(int, s1.split())
A = list(map(int, s2.split()))
B = list(map(int, s3.split()))
# Вспомогательный список
# B[i][0] - масимальная цена продажи в этот день и позже
# B[i][1] - индекс дня с максимальной ценой продажи
B[-1] = (B[-1], -1)
for i in range(2,len(B)):
~~~~if B[-i] > B[-i+1][0]:
~~~~~~~~B[-i] = (B[-i], -i)
~~~~else:
~~~~~~~~B[-i] = B[-i+1]
a_mn = A[0]# минимальная цена покупки не позже текущего дня
a_mni = 0# индекс для с минимальной ценой покупки
mx = x# максимальные деньги после покупки-продажи
mx_ij = (-1,-1)# дни покупки и продажи, нумерация с 1
for i in range(len(A)-1):# -1 потому, что покупать в последний день нельзя
~~~~if A[i] < a_mn:
~~~~~~~~a_mn = A[i]
~~~~~~~~a_mni = i
~~~~n_buy = x // a_mn# число купленных
~~~~rest = x % a_mn# сдача
~~~~x_sell = n_buy * B[i+1][0] + rest# деньги после продажи в этот день
~~~~if x_sell > mx:
~~~~~~~~mx = x_sell
~~~~~~~~mx_ij = (i+1, len(B) + B[i+1][1] +1)
print(mx)
print(*mx_ij)
Эдуард Лотов
Спасибо Вам огромное!
n, x = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
maxa,minb=max(a),min(b)
minind,maxind=b.index(minb),a.index(maxa)
kvoak=x//minb
if minind < maxind and maxa/minb > 1:
~~print ((maxa-minb)*kvoak,'\n',minind+1, maxind+1)
else: print ('-1 -1')
В ответе на первый пример, видимо, опечатка... Акции выгоднее всего продать не на 5-й день, а на 4-й, когда за них дают по 4 рубля! Покупать же их выгодно на 1-й или 3-й день по 1 рублю. Заработанная сумма правильная (4-1)*1000=3000.
Второй пример - правильный.
a = list(map(int, input().split()))
b = list(map(int, input().split()))
maxa,minb=max(a),min(b)
minind,maxind=b.index(minb),a.index(maxa)
kvoak=x//minb
if minind < maxind and maxa/minb > 1:
~~print ((maxa-minb)*kvoak,'\n',minind+1, maxind+1)
else: print ('-1 -1')
В ответе на первый пример, видимо, опечатка... Акции выгоднее всего продать не на 5-й день, а на 4-й, когда за них дают по 4 рубля! Покупать же их выгодно на 1-й или 3-й день по 1 рублю. Заработанная сумма правильная (4-1)*1000=3000.
Второй пример - правильный.
Роман Гордеев
Неправильное решение. Задача сложнее. Возможна ситуация, что оптимальны цены покупки/продажи не равны min/max ценам.
Сценарий: сначала цена падает, потом растёт, но не доходит до начальной цены. Потом падает ещё ниже, чем при первом падении.
Сценарий: сначала цена падает, потом растёт, но не доходит до начальной цены. Потом падает ещё ниже, чем при первом падении.
Ермек Мухамбетов
"В ответе на первый пример, видимо, опечатка... Акции выгоднее всего продать не на 5-й день, а на 4-й, когда за них дают по 4 рубля! Покупать же их выгодно на 1-й или 3-й день по 1 рублю."
5 1000
2 3 1 4 3
1 2 1 2 3
Вы попутали строки с ценами покупки и ценами продажи. Продажа самая нижняя.
И расчет результата у Вас неправильный,
не (4-1)*1000,
а 1000//1*4 + 1000%1 = 4000
а учитывая, что сначала цены покупки, а ниже цены продажи, то
1000//1*3 + 1000%1 = 3000
5 1000
2 3 1 4 3
1 2 1 2 3
Вы попутали строки с ценами покупки и ценами продажи. Продажа самая нижняя.
И расчет результата у Вас неправильный,
не (4-1)*1000,
а 1000//1*4 + 1000%1 = 4000
а учитывая, что сначала цены покупки, а ниже цены продажи, то
1000//1*3 + 1000%1 = 3000
Это ваша первая задача на оптимизацию кода?
Для ускорения работы нужно НЕ делать того, что делать не нужно, избегая или минимизируя повторения. В данном случае в каждом цикле вы обрезаете массив, просматриваете весь срез на предмет максимума, а потом ещё раз просматриваете до поиска индекса этого максимума.
Для начала можно не пользоваться стандартными функциями, и искать в цикле ручками без срезов и повторений поиска индекс и максимум одновременно.
Второй этап оптимизации. Как не трудно заметить, пока вы в цикле не достигнете индекса максимума, результат поиска не изменится. (вы это заметили)
Последний вариант, заранее обработать массив B, создав служебные структуры, чтобы получать ответ о максимуме и индексе для каждого i без просмотра массива, используя эти структуры.
Примерно так оптимизируется код в реальной жизни. Сначала устраняются явные косяки кода без вмешательства в алгоритм, если не повезёт, то нужно искать какую-то изюминку, ускоряя работу, и в самом последнем случае сесть и переделать весь алгоритм.
ЗЫ
Ответы не любят пробелы в начале строк, а разработчики не сделали исключение для раздела Python'а, код на нём удобнее читать на скриншоте или на специализированном сайте обмена кодами типа pastebin
Такой https://ideone.com/G8bmax код приятнее.
Для ускорения работы нужно НЕ делать того, что делать не нужно, избегая или минимизируя повторения. В данном случае в каждом цикле вы обрезаете массив, просматриваете весь срез на предмет максимума, а потом ещё раз просматриваете до поиска индекса этого максимума.
Для начала можно не пользоваться стандартными функциями, и искать в цикле ручками без срезов и повторений поиска индекс и максимум одновременно.
Второй этап оптимизации. Как не трудно заметить, пока вы в цикле не достигнете индекса максимума, результат поиска не изменится. (вы это заметили)
Последний вариант, заранее обработать массив B, создав служебные структуры, чтобы получать ответ о максимуме и индексе для каждого i без просмотра массива, используя эти структуры.
Примерно так оптимизируется код в реальной жизни. Сначала устраняются явные косяки кода без вмешательства в алгоритм, если не повезёт, то нужно искать какую-то изюминку, ускоряя работу, и в самом последнем случае сесть и переделать весь алгоритм.
ЗЫ
Ответы не любят пробелы в начале строк, а разработчики не сделали исключение для раздела Python'а, код на нём удобнее читать на скриншоте или на специализированном сайте обмена кодами типа pastebin
Такой https://ideone.com/G8bmax код приятнее.
Yan Erlats
Я быстрее написал программу из нескольких строк, чем прочел этот, бесспорно, поучительный текст... :)))
n, x = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
maxa,minb=max(a),min(b)
minind,maxind=b.index(minb),a.index(maxa)
kvoak=x//minb
if minind < maxind and maxa/minb > 1:
~~print ((maxa-minb)*kvoak,'\n',minind+1, maxind+1)
else: print ('-1 -1')
n, x = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
maxa,minb=max(a),min(b)
minind,maxind=b.index(minb),a.index(maxa)
kvoak=x//minb
if minind < maxind and maxa/minb > 1:
~~print ((maxa-minb)*kvoak,'\n',minind+1, maxind+1)
else: print ('-1 -1')
Оралбаев Бахытжан
"Такой https://ideone.com/G8bmax код приятнее."
Forbidden
Напомнило песенку:
" У нас есть ТАКИЕ!!! приборы.
Но мы вам о них не расскажем!" (С) Манго-Манго
Forbidden
Напомнило песенку:
" У нас есть ТАКИЕ!!! приборы.
Но мы вам о них не расскажем!" (С) Манго-Манго
Эдуард Лотов
Подсказка:
"Обратите внимание, что мы максимизируем не прибыль от покупки-продажи акции, а сумму денег на момент продажи, то есть надо учитывать и оставшиеся от покупки средства".
"Обратите внимание, что мы максимизируем не прибыль от покупки-продажи акции, а сумму денег на момент продажи, то есть надо учитывать и оставшиеся от покупки средства".
ясно.
N, money = map(int, input('Кол-во дней и началаьная сумма: ').split())
buy = list(map(int, input('Цена покупки: ').split()))
sell = list(map(int, input('Цена продажи: ').split()))
bestseller = 0
best_buy, best_sell = -2, -2
for i in range(N - 1): # по условию, акции нельзя продать в день покупки
~price = max(sell[i + 1:])
~if price - buy[i] > bestseller:
~~bestseller = price - buy[i]
~~best_buy, best_sell = i, sell.index(price)
if bestseller > 0:
~money = money // buy[best_buy] * sell[best_sell] + money % buy[best_buy]
print(money)
print(best_buy + 1, best_sell + 1)
P.S.
'~' = отступ в четыре пробела
buy = list(map(int, input('Цена покупки: ').split()))
sell = list(map(int, input('Цена продажи: ').split()))
bestseller = 0
best_buy, best_sell = -2, -2
for i in range(N - 1): # по условию, акции нельзя продать в день покупки
~price = max(sell[i + 1:])
~if price - buy[i] > bestseller:
~~bestseller = price - buy[i]
~~best_buy, best_sell = i, sell.index(price)
if bestseller > 0:
~money = money // buy[best_buy] * sell[best_sell] + money % buy[best_buy]
print(money)
print(best_buy + 1, best_sell + 1)
P.S.
'~' = отступ в четыре пробела
Оралбаев Бахытжан
В код не вникал, но для
=========
5 1000
5 3 7 1 4
4 2 6 1 3
1999
2 3
>>>
явно ошибка.
Так как купив в 4-й день 1000 акций по 1, можно продать их в 5-й день по 3 и иметь не 1999, а 3000.
=========
5 1000
5 3 7 1 4
4 2 6 1 3
1999
2 3
>>>
явно ошибка.
Так как купив в 4-й день 1000 акций по 1, можно продать их в 5-й день по 3 и иметь не 1999, а 3000.
Эдуард Лотов
Спасибо, но код не проходит по времени...
Yaguar Yaguar
Спасибо за замечание, исправил и доработал код:
N, money = map(int, input('Кол-во дней и начальная сумма: ').split())
buy = list(map(int, input('Цена покупки: ').split()))
sell = list(map(int, input('Цена продажи: ').split()))
bestseller = 0
best_buy, best_sell = -2, -2
for i in range(N - 1): # по условию, акции нельзя продать в день покупки
~price = max(sell[i + 1:])
~if price // buy[i] > bestseller:
~~bestseller = price // buy[i]
~~best_buy, best_sell = i, sell.index(price)
~elif price // buy[i] == bestseller and bestseller > 0:
~~if money // buy[i] > money // buy[best_buy]:
~~~best_buy, best_sell = i, sell.index(price)
if bestseller > 0:
~money = money // buy[best_buy] * sell[best_sell] + money % buy[best_buy]
print(money)
print(best_buy + 1, best_sell + 1)
N, money = map(int, input('Кол-во дней и начальная сумма: ').split())
buy = list(map(int, input('Цена покупки: ').split()))
sell = list(map(int, input('Цена продажи: ').split()))
bestseller = 0
best_buy, best_sell = -2, -2
for i in range(N - 1): # по условию, акции нельзя продать в день покупки
~price = max(sell[i + 1:])
~if price // buy[i] > bestseller:
~~bestseller = price // buy[i]
~~best_buy, best_sell = i, sell.index(price)
~elif price // buy[i] == bestseller and bestseller > 0:
~~if money // buy[i] > money // buy[best_buy]:
~~~best_buy, best_sell = i, sell.index(price)
if bestseller > 0:
~money = money // buy[best_buy] * sell[best_sell] + money % buy[best_buy]
print(money)
print(best_buy + 1, best_sell + 1)
Похожие вопросы
- Python задача линейной регрессии
- Не понимаю как выявить у кода (алгоритма ) сложность кто поможет с решением и объяснит как получил (выявил) Python
- Python - Алгоритмы структур данных
- Как это сделать в python или какой алгоритм для этого использовать?
- Окончил курсы на степике по Python что делать дальше?
- Python программирование. Помогите написать программу.
- Нейронные сети на Python 3.4
- Помогите, как сделать авторизацию в программе на python?
- Что писать на Python?
- Есть ли смысл изучать python