风口上的猪-中国牛市

来源:互联网 发布:九之濑遥cos淘宝全套 编辑:程序博客网 时间:2024/05/12 10:25
参考文献: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/51073838public 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;// 第一个肯定赋值为0int 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();// 最后一个肯定赋值为0dpr[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;}}


原创粉丝点击