leetcode 188---Best Time to Buy and Sell Stock IV
来源:互联网 发布:红帽linux是什么 编辑:程序博客网 时间:2024/05/22 04:50
问题描述:
Say you have an array for which the ith element is the price of a given stock on day i.
给你一个数组,里边的第i个元素存储的是股票在第i天的价格
Design an algorithm to find the maximum profit. You may complete at most k transactions.
允许最多完成k次交易(买进卖出k次),设计算法找出最大收益。
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
不能同时进行多次交易(在你再一次买进之前必须先卖出)。
问题求解:
特殊动态规划法。传统的动态规划我们会这样想,到第i天时进行j次交易的最大收益,要么等于到第i-1天时进行j次交易的最大收益(第i天价格低于第i-1天的价格),要么等于到第i-1天时进行j-1次交易,然后第i天进行一次交易(第i天价格高于第i-1天价格时)。于是得到动规方程如下(其中diff = prices[i] – prices[i – 1]):
profit[i][j] = max(profit[i – 1][j], profit[i – 1][j – 1] + diff)
看起来很有道理,但其实不对,为什么不对呢?因为diff是第i天和第i-1天的差额收益,如果第i-1天当天本身也有交易呢,那么这两次交易就可以合为一次交易,这样profit[i – 1][j – 1] + diff实际上只进行了j-1次交易,而不是最多可以的j次,这样得到的最大收益就小了。
那么怎样计算第i天进行交易的情况的最大收益,才会避免少计算一次交易呢?我们用一个局部最优解和全局最有解表示到第i天进行j次的收益,这就是该动态规划的特殊之处。
定义local[i][j]为在到达第i天时最多可进行j次交易并且最后一次交易在最后一天卖出的最大利润,此为局部最优。global[i][j]为在到达第i天时最多可进行j次交易的最大利润,此为全局最优 。它们二者的关系如下:
(其中diff = prices[i] – prices[i – 1])
local[i][j] = max(global[i – 1][j – 1] + max(diff, 0), local[i – 1][j] + diff)global[i][j] = max(global[i – 1][j], local[i][j])局部最优值是比较前一天并少交易一次的全局最优加上大于0的差值,和前一天的局部最优加上差值后相比,两者之中取较大值,而全局最优比较局部最优和前一天的全局最优。
其中的local[i – 1][j] + diff就是为了避免第i天交易和第i-1天交易合并成一次交易而少一次交易收益。
参考:
http://www.cnblogs.com/grandyang/p/4295761.html
http://www.cnblogs.com/grandyang/p/4295761.html
代码:时间O(n),空间O(k)。
class Solution {public: int maxProfit(int k, vector<int>& prices) { int n = prices.size(); if(n <= 1){ return 0; } //k大于天数时,退化成Best Time to Buy and Sell Stock II问题 if(k >= n){ return maxProfit2(prices); } vector<int> local(k+1); vector<int> global(k+1); //两层for循环实现二维数组,比如global[i][j] //可由i循环下的global[j]实现 for(int i=1;i<n;i++){ int diff = prices[i] - prices[i-1]; for(int j=k;j>0;j--){ local[j]=max(global[j-1]+max(diff,0),local[j]+diff); global[j]=max(global[j],local[j]); } } return global[k]; } int maxProfit2(vector<int>& prices){ int n = prices.size(); int profit=0; int max_profit=0; for(int i=1;i<n;i++){ if(prices[i] > prices[i-1]){ profit=prices[i]-prices[i-1]; max_profit += profit; } } return max_profit; }};
- LeetCode(188) Best Time to Buy and Sell Stock IV
- leetcode 188---Best Time to Buy and Sell Stock IV
- leetcode 188: Best Time to Buy and Sell Stock IV
- 188 Best Time to Buy and Sell Stock IV [Leetcode]
- [LeetCode 188] Best Time to Buy and Sell Stock IV
- LeetCode #188: Best Time to Buy and Sell Stock IV
- LeetCode 188 - Best Time to Buy and Sell Stock IV
- LeetCode 188 Best Time to Buy and Sell Stock IV
- Leetcode 188 Best Time to Buy and Sell Stock IV
- [LeetCode] Best Time to Buy and Sell Stock IV
- leetcode: Best Time to Buy and Sell Stock IV
- Best Time to Buy and Sell Stock IV -- leetcode
- Best Time to Buy and Sell Stock IV--LeetCode
- LeetCode : Best Time to Buy and Sell Stock III & IV
- Best Time to Buy and Sell Stock IV Leetcode Java
- LeetCode: Best Time to Buy and Sell Stock IV
- LeetCode Best Time to Buy and Sell Stock IV
- [leetcode] 188.Best Time to Buy and Sell Stock IV
- oralce初始化
- 唐山哪个yiyuan看小孩自闭症好
- java基础整理のstatic关键字
- Linux Tools Intro - CMake build and install
- IOS开发中的几种设计模式介绍
- leetcode 188---Best Time to Buy and Sell Stock IV
- 基于javacv的数字图像处理
- 什么是准货币,准货币包括哪些
- 唐山哪儿治疗自闭症专业
- iOS使用UITableView从plist中选择省市区
- git
- SQLite的简介
- iOS多线程编程之NSOperation和NSOperationQueue的使用
- 第12周-阅读、修改和运行关于交通工具类的程序,回答问题,以理解相关技术方法