동적 기획의 주식 매매
Best Time to Buy and Sell Stock
한 번만 매매하여 최대 이윤을 구할 수 있다
이동한 후 수조를 두루 훑어보고 i일째 팔면 얻을 수 있는 최대 이윤, 즉
i ( ) - 1~i-1 ( )
을 구한다.상태 전환 방정식:
max_profit[i] = max(price[i] - min_buy_price[i-1], max_profit[i-1])
min_buy_price[i] = min(price[i], min_buy_price[i-1])
import unittest
class Solution:
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
if len(prices) < 2:
return 0
max_profit = 0
min_buy_price = prices[0]
for price in prices:
if price > min_buy_price:
max_profit = max(max_profit, price - min_buy_price)
else:
min_buy_price = min(min_buy_price, price)
return max_profit
class TestSolution(unittest.TestCase):
def setUp(self):
self.s = Solution()
def test_one(self):
input = [7, 1, 5, 3, 6, 4]
self.assertEqual(self.s.maxProfit(input), 5)
def test_two(self):
input = [7, 6, 4, 3, 1]
self.assertEqual(self.s.maxProfit(input), 0)
if __name__ == "__main__":
unittest.main()
Best Time to Buy and Sell Stock II
여러 차례 매매를 허용하여 최대 이윤을 구하다
i일에는 2가지 상태가 있다. 주식 보유
own[i]
, 주식 미보유no_own[i]
이면 그 상태 방정식은 다음과 같다.own[i] = max(own[i-1], no_own[i-1] - price[i])
no_own[i] = max(own[i-1] + price[i], no_own[i-1])
상태 전환 방정식:
own[i] = max(own[i-1], no_own[i-1] - price[i])
no_own[i] = max(own[i-1] + price[i], no_own[i-1])
import unittest
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
if len(prices) < 2:
return 0
own = [0] * len(prices)
no_own = [0] * len(prices)
own[0] = -prices[0]
for i in range(1, len(prices)):
own[i] = max(own[i-1], no_own[i-1] - prices[i])
no_own[i] = max(no_own[i-1], own[i] + prices[i])
return no_own[-1]
class TestSolution(unittest.TestCase):
def test_one(self):
prices = [7,1,5,3,6,4]
s = Solution()
print(s.maxProfit(prices))
def test_two(self):
prices = [1, 2, 3, 4, 5]
s = Solution()
print(s.maxProfit(prices))
if __name__ == "__main__":
unittest.main()
Best Time to Buy and Sell Stock III
최대 두 번의 임의 매매로 최대 이윤을 구하다
i일에는 2가지 상태가 있는데 k는 k차 왕복 거래라고 한다. 주식 보유
own[k][i]
, 주식 보유no_own[k][i]
가 없으면 그 상태 방정식은 다음과 같다.own[k][i] = max(own[k][i-1], no_own[k-1][i-1] - price[i])
no_own[k][i] = max(own[k][i-1] + price[i], no_own[k][i-1])
상태 전환 방정식:
own[k][i] = max(own[k][i-1], no_own[k-1][i-1] - price[i])
no_own[k][i] = max(own[k][i-1] + price[i], no_own[k][i-1])
import unittest
from pprint import pprint
class Solution:
def maxProfit(self, prices):
if len(prices) < 2:
return 0
length = len(prices)
own = [[0]*(length) for i in range(3)]
no_own = [[0]*(length) for i in range(3)]
own[1][0] = own[2][0] = -prices[0]
for k in range(1,3):
for j in range(1, length):
own[k][j] = max(own[k][j-1], no_own[k-1][j-1] - prices[j])
no_own[k][j] = max(no_own[k][j-1], own[k][j-1] + prices[j])
return no_own[-1][-1]
class TestSolution(unittest.TestCase):
def setUp(self):
self.s = Solution()
def test_one(self):
input = [3, 3, 5, 0, 0, 3, 1, 4]
self.assertEqual(self.s.maxProfit(input), 6)
def test_two(self):
input = [1, 2, 3, 4, 5]
self.assertEqual(self.s.maxProfit(input), 4)
if __name__ == "__main__":
unittest.main()
Best Time to Buy and Sell Stock IV
최대 k회 임의 매매, 최대 이윤 추구
마찬가지로 k가 비교적 클 수 있기 때문에 공간을 절약하기 위해 우리는
k%2
를 이용하여 공간을 절약한다. 왜냐하면 매번 k차 거래는 지난번 거래와 관련이 있기 때문이다.단지 위의 최적화만으로는 부족하다. k가 클 수 있기 때문에 k>=len(prices)//2
만 하면 Best Time to Buy and Sell Stock II
의 문제로 바뀌어 많은 계산량을 감소시켰다.import unittest
class Solution:
def maxProfit(self, k, prices):
if len(prices) < 2:
return 0
length = len(prices)
if k >= length//2:
own = [0] * length
no_own = [0] * length
own[0] = -prices[0]
for i in range(1, length):
own[i] = max(own[i-1], no_own[i-1] - prices[i])
no_own[i] = max(no_own[i-1], own[i] + prices[i])
return no_own[-1]
own = [[0]*(length) for i in range(2)]
no_own = [[0]*(length) for i in range(2)]
own[0][0] = own[1][0] = -prices[0]
for k in range(0, k):
k = k % 2
own[k][0] = -prices[0]
for j in range(1, length):
own[k][j] = max(own[k][j-1], no_own[k-1][j-1] - prices[j])
no_own[k][j] = max(no_own[k][j-1], own[k][j-1] + prices[j])
return max(no_own[0][-1], no_own[1][-1])
class TestSolution(unittest.TestCase):
def setUp(self):
self.s = Solution()
def test_one(self):
input = [2, 4, 1]
self.assertEqual(self.s.maxProfit(2,input), 2)
def test_two(self):
input = [3, 2, 6, 5, 0, 3]
self.assertEqual(self.s.maxProfit(2, input), 7)
def test_three(self):
input = [1, 2]
self.assertEqual(self.s.maxProfit(1, input), 1)
if __name__ == "__main__":
unittest.main()
Best Time to Buy and Sell Stock with Cooldown
임의의 거래는 가능하나 주식을 판 다음날은 거래가 허용되지 않는다
i일에는 2가지 상태가 있다. 주식 보유
own[i]
, 주식 미보유no_own[i]
이면 그 상태 방정식은 다음과 같다.own[i] = max(own[i-1], no_own[i-2] - price[i])
no_own[i] = max(own[i-1] + price[i], no_own[i-1])
상태 전환 방정식:
own[i] = max(own[i-1], no_own[i-2] - price[i])
no_own[i] = max(own[i-1] + price[i], no_own[i-1])
import unittest
class Solution:
def search(self, nums, target):
if len(nums) == 0:
return -1
l = 0
h = len(nums) - 1
while l < h:
m = l + (h-l)//2
if nums[m] <= target:
l = m + 1
elif nums[m] >= target:
h = m
pos = -1
if nums[l] > target:
pos = l
return pos
class TestSolution(unittest.TestCase):
def setUp(self):
self.s = Solution()
def test_one(self):
input = [-1, 0, 3, 3, 5, 9, 12]
self.assertEqual(self.s.search(input, 3), 4)
def test_two(self):
input = [-1, 0, 3, 3, 5, 9, 12]
self.assertEqual(self.s.search(input, 2), 2)
def test_three(self):
input = [0]
self.assertEqual(self.s.search(input, 0), -1)
if __name__ == "__main__":
unittest.main()
Best Time to Buy and Sell Stock with Transaction Fee
임의로 여러 건 거래할 수 있지만, 매번 거래할 때마다 일정한 비용을 지불해야 한다fee
i일에는 2가지 상태가 있다. 주식 보유
own[i]
, 주식 미보유no_own[i]
이면 그 상태 방정식은 다음과 같다.own[i] = max(own[i-1], no_own[i-1] - price[i])
no_own[i] = max(own[i-1] + price[i] - fee, no_own[i-1])
상태 전환 방정식:
own[i] = max(own[i-1], no_own[i-1] - price[i])
no_own[i] = max(own[i-1] + price[i] - fee, no_own[i-1])
import unittest
class Solution:
def maxProfit(self, prices, fee):
"""
:type prices: List[int]
:type fee: int
:rtype: int
"""
length = len(prices)
if len(prices) < 2:
return 0
last_own = -prices[0]
last_no_own = 0
for i in range(1, length):
own = max(last_own, last_no_own - prices[i])
last_no_own = max(last_no_own, last_own + prices[i] - fee)
last_own = own
return last_no_own
class TestSolution(unittest.TestCase):
def setUp(self):
self.s = Solution()
def test_one(self):
input = [1, 3, 2, 8, 4, 9]
self.assertEqual(self.s.maxProfit(input, 2), 8)
def test_two(self):
pass
if __name__ == "__main__":
unittest.main()
총결산
처음에 이 문제들을 풀 때 어디서부터 손을 대야 할지 모르겠지만 이 몇 문제의 훈련을 거친 후에 대부분의 동태 계획에 대해 분석할 수 있다. 상태 방정식이 유도된 후에 초기 값을 확정하면 최종 결과를 얻을 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.