股票的最大利润 (DP求解)

股票的最大利润 (DP求解)

题目描述:假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?LeetCode链接

image-20210823133427434

题目分析:根据示例,我们发现需要找出给定数组中两个数字之间的最大差值(即,最大利润)。此外,第二个数字(卖出价格)必须大于第一个数字(买入价格)。

暴力求解

假设共有n天,第i天买入,第j天卖出,并且卖出价格必须大于买入价格,所以依次以第1天买入,第2 3 4….n天卖出,第2天买入,第3 4 5 6 …n天卖出,找出其中的最大值即可。

 /**
     * 暴力法
     * @param prices
     * @return
     */
   public int maxProfit(int[] prices)
    {
        //定义变量保存最大值,初值为0
        int max = 0;
        //临时变量,记录第j天卖出的价格
        int gain;
        //假设第i天买入,第j天卖出
        for (int i = 0; i < prices.length - 1; i++)
        {
            for (int j = i + 1; j < prices.length; j++)
            {
                //第i天买入,第j天卖出所赚的钱
                gain = prices[j] - prices[i];
                //找到最大值
                if (gain > max)
                {
                    max = gain;
                }
            }
        }
        return max;
    }

动态规划求解

分析:假设dp[i]第i天的最大利润

我们想要求第i天的最大利润,我们就需要知道 前一日的最大利润dp[i-1]第i天的卖出的最大利润中的最大值prices[i]-min[0,i] ,这两个值谁大,谁就是第i天的最大利润。

prices[i]-min[0,i] 解释:prices[i]为当天卖出价格 ,min[0,i]为前i日最低价格,这样就是当天的最大利润了

因此 转移方程为:dp[i]=Max(dp[i-1],prices[i]-min[0,i])

综上,代码如下

public static int maxProfit(int[] prices)
    {
        int[] dp = new int[prices.length];
        int[] minCost = new int[prices.length];//记录前N天中的最小值
        int min = Integer.MAX_VALUE;
        //创建记录前i天最小买入价格的数组
        for (int i = 0; i < prices.length; i++)
        {
            if (prices[i] < min)
            {
                min = prices[i];
            }
            minCost[i] = min;
        }
        //动态规划构造dp数组
        for (int i = 1; i < prices.length; i++)
        {
            min = Math.min(minCost[i], prices[i]);
            dp[i] = Math.max(dp[i - 1], prices[i] - min);
        }
        //找出dp数组中的最大值
        int max = 0;
        for (int i = 0; i < dp.length; i++)
        {
            if (max < dp[i])
            {
                max = dp[i];
            }
        }
        return max;
    }

优化动态规划

  • 对于前i天的最低价格min[0,i],可以在dp循环中,使用一个变量minCost来记录即可

    优化后转移方程为:dp[i]=Max(dp[i-1],prices[i]-minCost)

  • 由于dp[i]只与dp[i-1] prices[i] minCost有关,因此用一个变量max替换dp数组即可

    优化后的转移方程为:max=Max(max,prices[i]-minCost)

综上,代码如下

 public int maxProfit2(int[] prices)
    {
        int minCost = Integer.MAX_VALUE;//记录前N天中的最小值
        int max = 0;
       for (int i = 0; i < prices.length; i++)
        {
          minCost = Math.min(minCost, prices[i]);//如果当天的最值小于之前的最小值,那么更新最小值
          max = Math.max(max, prices[i] - minCost);//比较昨天的最大利润和今天的最大利润,其中最大值为今天的最大利润
        }
        return max;
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
dp求解电路布线问题是一种常用的布线算法。该算法通过动态规划的思想,将整个布线问题划分为若干个子问题,并通过求解子问题的最优解来得到整体的最优解。 在电路布线问题中,我们需要将一些电子元件(比如电阻、电容等)连接在一起,形成一个电路板。但是由于电路板上空间有限,并且元件之间有一定的连接规则和限制条件,因此如何布置这些电子元件,使得电路性能达到最优,就成为了一个布线问题。 dp求解电路布线问题的关键是定义状态和状态转移方程。我们可以将电路板划分为若干个小格子,每个格子可以放置一个元件或者被留空。然后我们定义一个二维的dp数组dp[i][j]表示前i个元件在前j个格子中的最优布线方案。状态转移方程可以通过考虑第i个元件放置在第j个格子和不放置在第j个格子两种情况来得到。 具体地,假设第i个元件需要和第k个元件连接(k < i),那么我们可以将第i个元件放置在第j个格子上(k < j < i),这样两个元件之间的连接就被实现了。而前k个元件的最优布线方案则可以通过dp[k][j]得到。然后我们遍历所有的k和j,找到使得总体性能最优的布线方案。 最后,通过计算得到的dp[n][m]即可得到整个电路布线问题的最优解,其中n表示元件的数量,m表示格子的数量。 总之,dp求解电路布线问题是一种通过动态规划思想划分问题并解决子问题的方法,能够得到电路布线问题的最优解。该算法在电子设计领域中应用广泛,可以有效提高布线的性能和效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值