最大化给定股票报价的利润,我在java中的解决方案

时间:2013-06-02 19:37:19

标签: java algorithm dynamic-programming

您将获得一组天的股票价格。每天,您可以购买一个单位的股票,出售已经购买的任何数量的股票单位,或者什么也不做。通过最佳规划您的交易策略,您可以获得的最大利润是多少?

示例(输入,即天数不同)

5 3 2 => profit = 0 // since the price decreases each day ,the max profit we can make = 0 
1 2 100 => profit = 197 
1 3 1 2 =>profit = 3 // we buy at 1 sell at 3 , then we buy at 1 and sell at 2 ..total profit = 3 

我的解决方案听起来与给出的答案完全一样,但由于某些原因,我的算法没有为某些大型测试用例返回正确的答案。任何人都可以看到我的代码有问题吗?

public class StockMax {

    private static final int BUY = 1;
    private static final int SELL = 0;

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    // TODO code application logic here
    Scanner stdin = new Scanner(System.in);

    //int T;

    //T = stdin.nextInt();

    //while (T-- > 0) {

        int N;
        int[] price;
        int[] opt;

        N = stdin.nextInt();

        price = new int[N];
        opt = new int[N];

        for (int i = 0; i < N; i++) {
            price[i] = stdin.nextInt();
        }

        opt[N - 1] = SELL;
        for (int i = N - 1; i > 0; i--) {

            if (price[i - 1] < price[i]) {
                opt[i - 1] = BUY;
            } else {
                opt[i - 1] = SELL;
            }
        }

        int own, profit, cost;
        own = profit = cost = 0;

        for (int i = 0; i < N; i++) {
            if (opt[i] == BUY) {
                own++;
                cost += price[i];
            } else {
                profit += ((own * price[i]) - cost);
                cost = own = 0;

            }
        }

        System.out.println(profit);
    }
}

这是我的代码的更新版本,如下面的评论中所述。我仍然失败了更多的测试用例然后通过。

import java.util.Scanner;

public class StockMax {

    private static final int BUY = 1;
    private static final int SELL = 0;
    private static int glb_max;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Scanner stdin = new Scanner(System.in);

        int T;

        T = stdin.nextInt();

        while (T-- > 0) {

            int N;
            int[] price;
            int[] opt;

            N = stdin.nextInt();

            price = new int[N];
            opt = new int[N];

            for (int i = 0; i < N; i++) {
                price[i] = stdin.nextInt();
            }

            opt[N - 1] = SELL;
            glb_max = price[N - 1];
            for (int i = N - 1; i > 0; i--) {

                if (price[i - 1] <= glb_max ) {
                    opt[i - 1] = BUY;
                } else {
                    opt[i - 1] = SELL;
                    glb_max = price[i - 1];
                }
            }

           /* 
             for(int i = 0; i < N;i++){
               System.out.print(opt[i] + " ");
            }
            */

            int own, profit, cost;
            own = profit = cost = 0;

            for (int i = 0; i < N; i++) {
                if (opt[i] == BUY) {
                    own++;
                    cost += price[i];
                } else {
                    profit += ((own * price[i]) - cost);
                    cost = own = 0;

                }
            }

            System.out.println(profit);

        }
    }
}

3 个答案:

答案 0 :(得分:2)

要测试这样的算法,您可以尝试编写一个蛮力测试人员,尝试所有购买/出售决策并测量可实现的最大利润。

我怀疑使用这种强力测试仪测试您当前的算法即使在一些小型测试案例中也会出现问题。

示例1

2 2 2 2 4

如果价格保持不变,当前算法选择卖出,因此在此示例中仅获得2个利润。

示例2

2 3 4 1 100

当价格减少时,当前算法会出售所有内容,因此会以4的价格出售所有商品,而不是等待价格100。

更好的算法

从最后一天倒退。

跟踪您将来看到的最优价格。

如果当前价格低于未来的最佳价格,请购买。

如果当前价格优于未来的最佳价格,则全部卖出。

否则,什么都不做。

答案 1 :(得分:2)

我刚刚在比赛网站上解决了这个问题。我会给你一个关于算法的基本概念,

1. smax = maximum stock price from the list
2. then find the profit by assuming you have bought all the stocks till smax 
   and you sell it at the price of smax
3. then check if smax is the last element of the stock price list 
   if yes then return profit as answer, 
   if no 
   then make a new list containing stock prices after smax to the last stock price
   and repeat steps 1-3 and keep adding profit of each iteration to get the final profit.

答案 2 :(得分:0)

这是一个递归解决方案。

public class BuysOrSellStocks {
    public static void main(String[] args) {
        int[] arr = {1,2,4,1,3};
        int profit = findProfit(0, arr.length, arr, 0);
        System.out.println("Final profit = "+ profit);
    }

    private static int findProfit(int start, int end, int[] arr, int profit) {
        if(start > arr.length-1)
            return profit;
        else {
            int maxIndex = findMaxIndex(arr, start, end-1);
            int noOfShares = 0;
            while(start<maxIndex) {
                profit = profit - arr[start];
                noOfShares++;
                start++;
            }
            profit = profit + (arr[maxIndex] * noOfShares);
            return findProfit(++maxIndex, end, arr, profit);
        }
    }

    private static int findMaxIndex(int[] arr, int start, int end) {
        int maxVal = Integer.MIN_VALUE;
        int maxInd = 0;
        for(int i=start; i<=end; i++)
            if(arr[i]>maxVal) {
                maxVal = arr[i];
                maxInd=i;
            }
        return maxInd;
    }
}