leetcode-188 买卖股票4
题目
给定一个数组表示股票每天的价格,最多交易k次,且手上最多只能拥有一支股票(即只能先卖出手上现有的股票再去购买新的股票),求最大的收益。 
    题目链接:买卖股票4 
    开始思路不清楚,参考了http://blog.csdn.net/dr_unknown/article/details/51939121 的解法。 
使用动态规划,先找清状态,题目中有两个主要变量天数,和交易次数,以及所要求的结果:最大的收益。那么可以构造状态dp[i][j],表示前i天最多交易j次获得的最大收益。 
    有了状态dp,可以找到递推公式:dp[i][j] = max{dp[i-1][j], dp[i-1][j-1] + prices[i] - prices[i-1]}:前i天进行j次的最大收益,等于前i-1天进行完最多j次交易的收益A和前i-1天进行完j-1次交易,且第i天进行最后一次交易的收益B的最大值。 
    但是这样有个问题,对于第二种情况,如果dp[i-1][j-1]中第j-1次交易是在第i-1天进行了卖出,那么 dp[i-1][j-1] + prices[i] - prices[i-1] 就相当于第j-1次交易是在第i天进行了卖出,最终相当于i天最多只进行了j-1次交易。 
    于是,需要细化状态,考虑使用状态 local[i][j]表示前i天最多进行j次交易,且最后一次卖出交易是在第i天完成,所获得的最大收益;global[i][j]表示前i天最多进行j次交易所获得的最大收益。 
于是有递归公式: local[i][j] = max{global[i-1][j-1] + max(prices[i] - prices[i-1], 0), local[i-1][j] + prices[i] - prices[i-1]}  
global[i][j] = max{local[i][j], global[i-1][j]}
    进一步的,状态第一维i只和i-1有关,可以进行空间压缩,将二维数组变成一维,于是有递推公式: local[j] = max{global[j-1] + max(prices[i] - prices[i-1], 0), local[j] + prices[i] - prices[i-1]}  
global[j] = max{local[j], global[j]}
但是需要注意j需要从高到低遍历,因为第i天交易j次的最优解依赖于第i-1天交易j-1次的最优解。 
    进行状态压缩时,数组的遍历方向很容易搞混,这是可以使用滚动数组,滚动数组一方面可以压缩空间,另一方面也不需要太过考虑数组的遍历方向。 local[new_scroll][j] = max(global[old_scroll][j-1] + max(diff, 0), local[old_scroll][j] + diff); 
global[new_scroll][j] = max(local[new_scroll][j], global[old_scroll][j]);
实现
class Solution {
public:
	int maxProfit(int k, vector<int> &prices) {
	    int n = prices.size();
	    if(n <= 1)
	        return 0;
	    if(k >= n)
	        return maxProfit2(prices);
	    for(int i = 0; i < 2; i ++){
	        local[i].assign(k + 1, 0);
	        global[i].assign(k + 1, 0);
	    }
	    int old_scroll = 0, new_scroll;
	    for(int i = 1; i < n; i ++){
	        int diff = prices[i] - prices[i-1];
	        new_scroll = 1 - old_scroll;
	        for(int j = 1; j <= k; j ++){
	            local[new_scroll][j] = max(global[old_scroll][j-1] + max(diff, 0), local[old_scroll][j] + diff);
	            global[new_scroll][j] = max(local[new_scroll][j], global[old_scroll][j]); //注意这里 local 为new_scroll
	        }
	        old_scroll = new_scroll;
	    }
	    return global[new_scroll][k];
	}
	int maxProfit2(vector<int>& prices){
	    int result = 0;
	    int n = prices.size();
	    for(int i = 1; i < n; i ++){
	        if(prices[i] > prices[i-1])
	            result += (prices[i] - prices[i-1]);
	    }
	    return result;
	}
private:
    vector<int> local[2];
    vector<int> global[2];
};
leetcode-188 买卖股票4的更多相关文章
- Java实现 LeetCode 188 买卖股票的最佳时机 IV
		
188. 买卖股票的最佳时机 IV 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意: 你不能同时参与多 ...
 - Leetcode 188.买卖股票的最佳时机IV
		
买卖股票的最佳时机IV 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意: 你不能同时参与多笔交易(你必 ...
 - leetcode 188. 买卖股票的最佳时机 IV
		
参见 本题采用了第一列初始化后,从左侧向右开始递推的方式,但从上往下递推应该也成立,以后尝试一下 想写一个普适性的适用于n天交易k次持有j股的状态方程但是有问题:对于交易次数过多的情况数组会超出界限: ...
 - Leetcode之动态规划(DP)专题-188. 买卖股票的最佳时机 IV(Best Time to Buy and Sell Stock IV)
		
Leetcode之动态规划(DP)专题-188. 买卖股票的最佳时机 IV(Best Time to Buy and Sell Stock IV) 股票问题: 121. 买卖股票的最佳时机 122. ...
 - 每日一题-——LeetCode(121)买卖股票的最佳时机
		
题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格.如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润.注意你不能在买入股票前卖出股票 ...
 - LeetCode《买卖股票的最佳时机》系列题目,最详解
		
目录 说在前面 引例:只能交易一次 一.动态数组定义 二.状态转移方程 三.初始化 四.优化 无限制买卖 一.动态数组定义 二.状态转移方程 三.初始化 四.优化 交易 2 次,最大利润? 一.动态数 ...
 - Leetcode——121. 买卖股票的最佳时机
		
题目描述:买卖股票的最佳时机 题目要求求解能获得最大利润的方式? 可以定一个二维数组 d [ len ] [ 2 ] ,其中d[ i ][ 0 ] 表示前i天可以获得的最大利润:d[ i ][ 1 ] ...
 - Leetcode 123.买卖股票的最佳时机III
		
买卖股票的最佳时机III 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 两笔 交易. 注意: 你不能同时参与多笔交易(你 ...
 - 【Leetcode】买卖股票-贪心算法
		
题目: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交易(你必 ...
 - Java实现 LeetCode 714 买卖股票的最佳时机含手续费(动态规划 || 迭代法)
		
714. 买卖股票的最佳时机含手续费 给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 :非负整数 fee 代表了交易股票的手续费用. 你可以无限次地完成交易,但是你每次交 ...
 
随机推荐
- 动画 CABasicAnimation animationWithKeyPath 一些规定的值
			
CABasicAnimation animationWithKeyPath Types When using the ‘CABasicAnimation’ from the QuartzCore Fr ...
 - APICloud:轻松6步完成App软件开发
			
现如今,谁不知道App绝对就是OUT,谁不用App简直没法过日子!但是说到App软件开发,不懂编程,不懂技术的人就一脸懵圈.在门外汉来看,App软件开发是一件非常困难的事情,然而APICloud却说, ...
 - VMware ESXI磁盘下载虚拟机迁移到另一台VMware ESXI
			
1.从10.8.9.156服务器下载虚拟机文件上传到10.8.9.160服务器使用. 2.选择虚拟文件夹点击下载到本地计算机. 3.浏览10.8.9.160数据存储. 4.把存放在本地计算机虚拟文件夹 ...
 - DuiLib学习笔记3——颜色探究
			
在前面两篇日志已经能使用xml了.今天准备好好的折腾一番,结果在颜色上却掉坑里了. 起初我在ps里取颜色为0104ff 这里01为R,04为G,ff为B 在控件的属性里有这样一个属性bkcolor=& ...
 - 成都PC网站建设需要考虑哪些费用呢
			
亿合科技PC建设小编分享下:成都PC网站建设需要考虑哪些费用呢?随互联网的发展,越来越多人想建设自己网站,站长最关心的问题之一就是网站建设需要多少钱.每个网站建设的费用都是不一样的,但是都需要涵盖几个 ...
 - 开发环境中biztalk项目设置注意事项(转)
			
适用版本:biztalk 2006 适用环境:开发测试环境 在开发过程中,在开发环境中,一定会是一个对项目不断的修改.编译.部署.测试,查看测试结果,发现有问题,然后回到开发环境再修改.编译.部署 ...
 - C# 中using的几个用途
			
参考文献 http://www.cnblogs.com/morningwang/archive/2008/03/12/1102952.html http://msdn.microsoft.com/zh ...
 - Using Yum Variables
			
You can use and reference the following built-in variables in yum commands and in all Yum configurat ...
 - C# 使用 Abot 实现 爬虫 抓取网页信息 源码下载
			
下载地址 ** dome **
 - asp.net core 通过 TeamCity 实现持续集成笔记
			
0x00 很早之前就想体验一把持续集成的快感,然后刚好手头上有个 asp.net core 的项目,就想来部署一下持续集成.一开始我是想用 Jenkins 的,弄了好半天,git 仓库没法同步下来,我 ...