题目
假定你来交易某只股票。
你的每次买或卖都限定为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,