LeetCode(C++)-动态规划(股票问题)

121. 买卖股票的最佳时机

代码:

class Solution {	//121. 买卖股票的最佳时机
	//动态规划五部曲:
	//1. 确定dp数组以及下标的含义:在第i天持有股票所得最多现金dp[i][0],在第i天不持有股票所得最多现金dp[i][1]
	//2. 确定递推公式:dp[i][0]=max(dp[i-1][0],-prices[i])  dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i])
	//3. dp数组如何初始化:dp[0][0]=-prices[0] dp[0][1]=0
	//4. 确定遍历顺序:从前向后遍历
	//5. 举例推导dp数组:
public:
	int maxProfit(vector<int>& prices) {
		int len = prices.size();
		if (len == 0)return 0;
		vector<vector<int>> dp(len,vector<int>(2));
		dp[0][0] = -prices[0];
		dp[0][1] = 0;
		for (int i = 1; i < len; ++i) {
			dp[i][0] = max(dp[i - 1][0], -prices[i]);
			dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
		}
		return dp[len - 1][1];
	}
};

122. 买卖股票的最佳时机 II

代码:

class Solution {	//122. 买卖股票的最佳时机 II   不买 买 卖出 三种状态
	//动态规划五部曲:
	//1. 确定dp数组以及下标的含义:在第i天持有股票所得最多现金dp[i][0],在第i天不持有股票所得最多现金dp[i][1],
	//2. 确定递推公式:dp[i]=max(dp[i-1][0],dp[i-1][1]-prices[i])  dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i])
	//3. dp数组如何初始化:dp[0][0]=-prices[0] dp[0][1]=0
	//4. 确定遍历顺序:从前向后遍历
	//5. 举例推导dp数组:
public:
	int maxProfit(vector<int>& prices) {
		int len = prices.size();
		if (len == 0)return 0;
		vector<vector<int>> dp(len,vector<int>(2));
		dp[0][0] = -prices[0];
		dp[0][1] = 0;
		for (int i = 1; i < len; ++i) {
			dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
			dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
		}
		return dp[len - 1][1];
	}
};

123. 买卖股票的最佳时机 III

代码:

class Solution {	//123. 买卖股票的最佳时机 III
	//动态规划五部曲:
	//1. 确定dp数组以及下标的含义:一天一共有五个状态:0,没有操作;1,第一次买入;2,第一次卖出;3,第二次买入;4,第二次卖出
	//2. 确定递推公式:dp[i][1]=max(dp[i-1][0]-prices[i],dp[i-1][1]);dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2]);
	//			dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
	//3. dp数组如何初始化:dp[0][0]=0;dp[0][1]=-prices[0];dp[0][2]=0;dp[0][3]=-prices[0];dp[0][4]=0;
	//4. 确定遍历顺序:从前向后
	//5. 举例推导dp数组:
public:
	int maxProfit(vector<int>& prices) {
		if (prices.size() == 0)return 0;
		vector<vector<int>> dp(prices.size(), vector<int>(5, 0));
		dp[0][1] = dp[0][3] = -prices[0];
		for (int i = 1; i < prices.size(); ++i) {
			dp[i][0] = dp[i - 1][0];
			dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]); 
			dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2]);
			dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]); 
			dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
		}
		return dp[prices.size() - 1][4];
	}
};

188. 买卖股票的最佳时机 IV

代码:

class Solution {	//188. 买卖股票的最佳时机 IV
	//动态规划五部曲:
	//1. 确定dp数组以及下标的含义:一天一共有2*k+1个状态:0,没有操作;1,第一次买入;2,第一次卖出;3,第二次买入;4,第二次卖出......
	//2. 确定递推公式:dp[i][1]=max(dp[i-1][0]-prices[i],dp[i-1][1]);dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2]);
	//			dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
	//			可以推出:奇数买入,偶数卖出,dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]); dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);
	//3. dp数组如何初始化:dp[0][0]=0;dp[0][1]=-prices[0];dp[0][2]=0;dp[0][3]=-prices[0];dp[0][4]=0;......
	//4. 确定遍历顺序:从前向后
	//5. 举例推导dp数组:
public:
	int maxProfit(int k, vector<int>& prices) {
		if (prices.size() == 0)return 0;
		vector<vector<int>> dp(prices.size(), vector<int>(2*k+1, 0));
		for (int j = 1; j < 2 * k; j+=2) {
			dp[0][j] = -prices[0];
		}
		for (int i = 1; i < prices.size(); ++i) {
			for (int j = 0; j < 2 * k - 1; j+=2) {
				dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);	//奇数,在沿用前一天的买入状态和沿用前一天的卖出状态今天买入之间选最大
				dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);	//偶数,在沿用前一天的卖出状态和沿用前一天的买入状态今天卖出之间选最大
			}
		}
		return dp[prices.size() - 1][2 * k];
	}
};

309. 最佳买卖股票时机含冷冻期

代码:

class Solution {	//309. 最佳买卖股票时机含冷冻期
	//动态规划五部曲:
	//1. 确定dp数组以及下标的含义:dp[i][j] 为第i天的状态为j,j可以为0,达到买入股票状态;1,达到保持卖出股票状态;2.达到今天卖出股票状态 3.冷冻期 昨天卖出了股票
	//2. 确定递推公式:dp[i][0]=max(dp[i-1][0],max(dp[i-1][3],dp[i-1][1])-prices[i])达到买入股票状态 (1)保持前一天的股票买入状态 (2)今天买入了股票,那么前一天要么是冷冻期,要是保持股票卖出状态
	//	dp[i][1]=max(dp[i-1][1],dp[i-1][3]) 达到保持卖出股票状态 (1) 前一天是渡过冷冻期的股票卖出状态 (2)前一天是冷冻期
	//	dp[i][2]=dp[i-1][0]+prices[i] 达到今天卖出股票状态 (1)前一天是买入股票状态 
	//	dp[i][3]=dp[i-1][2] 冷冻期 (1)前一天是股票卖出
	//3. dp数组如何初始化:dp[0][0]=-prices[0] 其余都为0
	//4. 确定遍历顺序:从前往后
	//5. 举例推导dp数组:
public:
	int maxProfit(vector<int>& prices) {
		int len = prices.size();
		if (len == 0)return 0;
		vector<vector<int>> dp(len, vector<int>(4, 0));
		dp[0][0] = -prices[0];
		for (int i = 1; i < len; ++i) {
			dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3], dp[i - 1][1]) - prices[i]);
			dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);
			dp[i][2] = dp[i - 1][0] + prices[i];
			dp[i][3] = dp[i - 1][2];
		}
		return max(dp[len - 1][3], max(dp[len - 1][1], dp[len - 1][2]));
	}
};

714. 买卖股票的最佳时机含手续费

代码:

class Solution {	//714. 买卖股票的最佳时机含手续费
	//动态规划五部曲:
	//1. 确定dp数组以及下标的含义:dp[i][j] 第i天的状态为j  j可以为0,保持股票买入的状态;1,保持股票卖出的状态
	//2. 确定递推公式:dp[i][0]=max(dp[i-1][0],dp[i-1][1]-prices[i]) 保持股票买入的状态 (1)保持前一天股票买入状态 (2)今天买入股票,用前一天股票卖出的状态-今天股票价格
	//	dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i]-fee) 保持股票卖出的状态 (1)保持前一天股票卖出状态 (2)今天卖出股票,要用前一天买入股票的状态+今天股票价格-手续费
	//3. dp数组如何初始化:dp[0][0]=-prices[0] dp[0][1]=0
	//4. 确定遍历顺序:从前往后
	//5. 举例推导dp数组:
public:
	int maxProfit(vector<int>& prices, int fee) {
		int len = prices.size();
		if (len == 0)return 0;
		vector<vector<int>> dp(len, vector<int>(2, 0));
		dp[0][0] = -prices[0];
		for (int i = 1; i < len; ++i) {
			dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
			dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee);
		}
		return max(dp[len - 1][0], dp[len - 1][1]);
	}
};

参考资料:

代码随想录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
一点通票据通软件通过计算机签发各种票据来代替手工操作,大大提高开票速度并减少错票现象,减轻各公司、企事业单位财务出纳人员的工作负担。我们追求软件易操作性、实用性。 一点通票据通软件功能特色: 1、只需输入小写金额,系统自动转换成大写金额;票据日期自动生成。 2、通打所有银行的可打印所有银行的支票、进帐单、电汇凭证、贷记凭证、业务委托书、承兑汇票、现金缴款单、汇票申请书、托收凭证、财政拨款单、同城实时凭证、外汇支款凭证、出纳自定义票据等。 3、转帐支票可自动转入进帐单,进帐单信息不用重复录入。并且可随时增加新成立的银行和外资银行及货币币种,新增外币支票大写英文形式,随心打印外币支票。 4、票据管理:用户可以对已经保存到数据库中的票据进行查询,修改和删除操作。而且可以将已经检索的票据进行打印。 5、票据各栏位的打印位置可在所见即所得下动态灵活调整字体、位置等。 6、对所有往来客户、自己单位银行信息及用途预先设置,开票时只需选择相应的客户,其开户行、帐号等信息自动调入,提高开票速度。且可将已有客户档案导入软件,减少信息的重复输入。 7、为了方便用户使用,本软件独创票据模板导入功能,真正做到所有银行(不是个别或几个银行)每票据都可以实现自身票据实样显示,方便用户因票证版式更新直接选用升级模板库,无需自己再设计。 一点通票据通软件截图

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海螺蜜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值