风口上的猪-中国牛市

参考文献:http://blog.csdn.net/li563868273/article/details/51073838
风口之下,猪都能飞。当今中国股市牛市,真可谓“错过等七年”。 给你一个回顾历史的机会,已知一支股票连续n天的价格走势,以长度为n的整数数组表示,数组中第i个元素(prices[i])代表该股票第i天的股价。 假设你一开始没有股票,但有至多两次买入1股而后卖出1股的机会,并且买入前一定要先保证手上没有股票。若两次交易机会都放弃,收益为0。 设计算法,计算你能获得的最大收益。 输入数值范围:2<=n<=100,0<=prices[i]<=100 
输入例子:
3,8,5,1,7,8

输出例子:
12

解析:动态规划思路,有0次,1次,2次机会操作股票,那么可以把数组以i为中间值分为前半段和后半段,0<=i<=n-1,dpl[i]表示从0到i-1天内的最大收益,dpr[i]表示从第i-1天到第n-1天内的最大收益,两者相加可求出总的最大收益


import java.sql.ResultSet;


public class Main {
	public static void main(String[] args) {
		int[] array = new int[] { 3, 8, 5, 1, 7, 8 };
		calculateMax3(array);
	}

	public static int calculateMax(int[] p) {
		int[] dpl=new int[p.length];
		//dpl[i]为从0开始到i的所有天中能获得的最大的收益,可能是其中的一段时间
		int length=p.length;
		dpl[0]=0;
		int min=0;
		//min为从第min天开始买入到第i天获得的收益
		int resl=0;
		for(int i=1;i<length;i++){
			if(p[i]>p[i-1]){
				resl=Math.max(p[i]-p[min], resl);//比较值为历史新低到当前天的最大收益和前i天历史最大值
				dpl[i]=resl;
				//若第二天上涨,有可能该天到买入收益最大,也有可能是股票回升
				//若股票回升,则还是为前i天最大值,即前i天最大收益仍为第min天到第某天
			}else {
				//若第二天下跌,则看是否跌出谷底,
				//若没有跌出谷底,则仍为前i-1天最大收益
				//若跌出谷底则重新计算最小值,从该天算后面的收益
				dpl[i]=dpl[i-1];
				if(p[i]<p[min]){
					min=i;
				}
			}
		}
		
		int[] dpr=new int[length];
		dpr[length-1]=0;
		int resr=0;
		int max=length-1;
		for(int i=length-2;i>=0;i--){
			if(p[i]<p[i+1]){
				resr=Math.max(p[max]-p[i], resr);
				dpr[i]=resr;
			}else {
				dpr[i]=dpr[i+1];
				if(p[i]>p[max]){
					max=i;
				}
			}
		}
		
		int res =0;
		for(int i=0;i<length;i++){
			res=Math.max((dpl[i]+dpr[i]), res);
		}
		
		
		System.out.println(res);
		
		return res;
	}

	/**
	 * 计算你能获得的最大收益
	 *
	 * @param prices
	 *            Prices[i]即第i天的股价
	 * @return 整型
	 */
	public static int calculateMax2(int[] prices) {

		int firstBuy = Integer.MIN_VALUE, firstSell = 0;
		int secondBuy = Integer.MIN_VALUE, secondSell = 0;
		for (int curPrice : prices) {
			firstBuy = Math.max(firstBuy, -curPrice);
			firstSell = Math.max(firstSell, firstBuy + curPrice);
			secondBuy = Math.max(secondBuy, firstSell - curPrice);
			secondSell = Math.max(secondSell, secondBuy + curPrice);
			System.out.println("firstBuy: " + firstBuy + ", firstSell: "
					+ firstSell + ", secondBuy: " + secondBuy
					+ ", secondSell: " + secondSell);
		}
		return secondSell;
	}
        
       // 来自http://blog.csdn.net/li563868273/article/details/51073838
	public static int calculateMax3(int[] prices) {
		// 记录[0..i]之间的最大收益
		int[] dpl = new int[prices.length];
		// 记录[i...length-1]的最大收益
		int[] dpr = new int[prices.length];
		dpl[0] = 0;// 第一个肯定赋值为0
		int minI = 0;
		// 扫描一次左边
		System.out.print("dpl[0]=0, ");
		for (int i = 1; i < dpl.length; i++) {
			// 如果大于等于
			if (prices[i] > prices[i - 1]) {
				dpl[i] = Math.max(prices[i] - prices[minI], dpl[i - 1]);
			} else {
				dpl[i] = dpl[i - 1];
				if (prices[i] < prices[minI])
					minI = i;
			}
			System.out.print("dpl[" + i + "]=" + dpl[i] + ", ");
		}
		System.out.println();
		// 最后一个肯定赋值为0
		dpr[prices.length - 1] = 0;
		int maxI = prices.length - 1;
		System.out.print("dpr[" + (prices.length - 1) + "]=0, ");
		for (int i = prices.length - 2; i >= 0; i--) {// 从右到左扫描一遍填充dpr数组,和从左边扫描一样
			if (prices[i] < prices[i + 1]) {
				dpr[i] = Math.max(prices[maxI] - prices[i], dpr[i + 1]);
			} else {
				dpr[i] = dpr[i + 1];
				if (prices[i] > prices[maxI]) {
					maxI = i;
				}
			}
			System.out.print("dpr[" + i + "]=" + dpr[i] + ", ");
		}
		System.out.println();
		int res = 0;
		for (int i = 0; i < prices.length - 1; i++) { // 比较得出最大值
			res = Math.max(dpl[i] + dpr[i], res);
			System.out.println("dpl[" + i + "]=" + dpl[i] + ",dpr[" + i + "]="
					+ dpr[i] + ",res=" + res);
		}
		return res;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值