股票两回合(算法入门题目007)

这是一篇关于股票交易算法的入门文章,探讨如何在限定4次交易操作的情况下,通过优化策略找到最大收益。首先从最直观的4层循环嵌套解法入手,然后分析并优化至线性复杂度的解决方案,与最大连续和问题相联系。文章提供两种代码实现,并鼓励读者深入理解相关问题,同时提供了在线讲解资源作为辅助学习。
摘要由CSDN通过智能技术生成

题目

假定你来交易某只股票。
你的每次买或卖都限定为1股。
你最多可进行4次交易(卖和卖各2次),
开始时,你手中无股票。
并且,必须等第一笔卖掉后,才能买第二笔。
每个时间点只能完成一次操作(买或卖)。
还要保证交易结束时,你手中无股票。

给出一天中的该股票价格序列,
请写一个程序计算可以获得的最大收益。

例如,序列是:
[10,22,5,75,65,80]
则返回值应为:87

分析

当然是先考虑最笨的办法。
逐一枚举 4 次操作的时间点,4 层循环嵌套。
两次收益求和,筛出最大值即可。
这里还要注意小陷阱,最多可操作4次,
也就是说,你可以操作 2 次,或 0 次。
当股价一路下滑的时候,你至少不要赔钱吧。

稍考虑一下这种解法,会发现存在许多重复的计算。
比如,当前一回合卖出点确定时,无论是什么时候买的,都与后一个回合的最大盈利无关了。
其实这个问题的优化与著名的《最大连续和》问题如出一辙。
只要准备几个数组,可以优化到 O(n) 的量级。

代码

先来个笨的。
注意最后别弄个负的盈利出来。

//problem007
public class A{
   
	static int f(int[] data){
   
		int res = 0;
		for(int a=0; a<data.length; a++){
   
			for(int b=a+1; b<data.length; b++){
   
				int x = data[b]-data[a];
				res = Math.max(res,x);
				for(int c=b+1; c<data.length; c++){
   
					for(int d=c+1; d<data.length; d++){
   
						int y = data[d]-data[c];
						res = Math.max(res,x+y);
					}
				}
			}
		}
		return res;
	}
	
	public static void main(String[] args){
   
		System.out.println(f(new int[]{
   10,22,5,75,65,80}));	
		System.out.println(f(new int[]{
   9,8,7,6,5,4,3,2,1}));
		System.out.println(f(new int[]{
   1,2,3,4,5,6,7,8,9}));
		System.out.println(f(new int[]{
   
			486,465,489,482,462,459,476,485,476,464,456,476,484,505,515,499,501,514,537,549,
			566,568,592,579,577,561,551,551,555,555,579,560,576,592,610,612,608,616,638,652,
			659,636,621,604,613,611,610,626,620,641,628,605,627,635,621,645,660,672,695,694,
			704,701,691,702,713,714,735,732,740,740,722,706,695,704,697,674,657,669,648,634,
			626,640,643,648,639,661,677,698,693,710,722,705,699,697,708,699,684,667,646,661,
			679,662,650,628,630,644,658,672,649,640,618,639,623,636,615,635,614,602,583,560,
			536,558,558,554,564,552,531,548,556,567,559,535,559,568,552,571,553,560,547,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值