Best Time to Buy and Sell Stock I\II\III\IV

  1. Best Time to Buy and Sell Stock(有一个数组,数组中第i个元素表示第i天的股票,如果你只有一次交易机会,买一次卖出一次,就出最大利润。)

    思路:动态规划法。从前向后遍历数组,记录当前出现过的最低价格,作为买入价格,并计算以当天价格出售的收益,作为可能的最大收益,整个遍历过程中,出现过的最大收益就是所求。O(n)的时间复杂度,O(1)的空间复杂度。
    主要代码:

min= Math.min(min,prices[i]); 
maxProfit = Math.max(maxProfit,prices[i]-min);
  1. Best Time to Buy and Sell Stock I(在上一题的基础上,条件改为可以进行多次交易,但是必须先买在卖)

    思路:贪心法。从前往后遍历数组,只要当天的价格高于前一天的价格,就算入收益。O(n)的时间复杂度,O(1)的空间复杂度。
    主要代码:int profit = prices[i]-prices[i-1]; if(profit>0) max += profit;

  2. Best Time to Buy and Sell Stock II(在上一题的基础上,条件改为最多只能进行两次交易)

    思路:动态规划法。以第i天为例,计算第i天之前进行一次交易的最大收益preProfit[i],和第i天之后进行一次交易的postProfit[i],遍历一遍之后求max(preProfit[i]+postProfit[i])为最大收益。其中求preProfit[i]和postProfit[i]的方法和I的一样。O(n)的时间复杂度,O(n)的空间复杂度。需要额外的两个数组preProfit和postProfit来保存对应的利润。

  3. Best Time to Buy and Sell Stock III (条件改为至少K次交易)(此题转载别人的解析)

    思路:特殊动态规划法。传统的动态规划我们会这样想,到第i天时进行j次交易的最大收益,要么等于到第i-1天时进行j次交易的最大收益(第i天价格低于第i-1天的价格),要么等于到第i-1天时进行j-1次交易,然后第i天进行一次交易(第i天价格高于第i-1天价格时)。于是得到动规方程如下(其中diff = prices[i] – prices[i – 1]):
    profit[i][j] = max(profit[i – 1][j], profit[i – 1][j – 1] + diff)

    看起来很有道理,但其实不对,为什么不对呢?因为diff是第i天和第i-1天的差额收益,如果第i-1天当天本身也有交易呢(也就是说第i-1天刚卖出了股票,然后又买入等到第i天再卖出),那么这两次交易就可以合为一次交易,这样profit[i – 1][j – 1] + diff实际上只进行了j-1次交易,而不是最多可以的j次,这样得到的最大收益就小了。

    那么怎样计算第i天进行交易的情况的最大收益,才会避免少计算一次交易呢?我们用一个局部最优解和全局最有解表示到第i天进行j次的收益,这就是该动态规划的特殊之处。

    用local[i][j]表示到达第i天时,最多进行j次交易的局部最优解;用global[i][j]表示到达第i天时,最多进行j次的全局最优解。它们二者的关系如下(其中diff = prices[i] – prices[i – 1]):
    local[i][j] = max(global[i – 1][j – 1] , local[i – 1][j] + diff)
    global[i][j] = max(global[i – 1][j], local[i][j])

    local[i][j]和global[i][j]的区别是:local[i][j]意味着在第i天一定有交易(卖出)发生,当第i天的价格高于第i-1天(即diff > 0)时,那么可以把这次交易(第i-1天买入第i天卖出)跟第i-1天的交易(卖出)合并为一次交易,即local[i][j]=local[i-1][j]+diff;当第i天的价格不高于第i-1天(即diff<=0)时,那么local[i][j]=global[i-1][j-1]+diff,而由于diff<=0,所以可写成local[i][j]=global[i-1][j-1]。global[i][j]就是我们所求的前i天最多进行k次交易的最大收益,可分为两种情况:如果第i天没有交易(卖出),那么global[i][j]=global[i-1][j];如果第i天有交易(卖出),那么global[i][j]=local[i][j]。
    参考:http://www.cnblogs.com/grandyang/p/4295761.html

    代码:时间O(n),空间O(n)

    int days = prices.length;
    if (k >= days) return maxProfit2(prices);
    
    int[][] local = new int[days][k + 1];
    int[][] global = new int[days][k + 1];
    
    for (int i = 1; i < days ; i++) {
        int diff = prices[i] - prices[i - 1];
    
        for (int j = 1; j <= k; j++) {
            local[i][j] = Math.max(global[i - 1][j - 1], local[i - 1][j] + diff);
            global[i][j] = Math.max(global[i - 1][j], local[i][j]);
         }
    }
    
    return global[days - 1][k];
    

    动规所用的二维辅助数组可以降为一维的,即只用大小为k的一维数组记录到达第i天时的局部最优解和全局最优解。需要注意的是,由于第i天时交易k次的最优解依赖于第i-1天时交易k-1次的最优解,所以数组更新应当从后往前(即从k到1)更新。

  4. Best Time to Buy and Sell Stock with Cooldown (可以交易多次,但是在每次在卖出股票后必须隔一天才能再买股票,有一天的冷冻期)

    思路:维护两个数组,数组buy表示买入的最大利润,它需要考虑第i天是否买入;数组sell表达卖出的最大利润,它需要考虑第i天是否卖出。然后写出下面的递推公式:
    buy[i] = max(buy[i-1], sell[i-2] - prices[i])
    sell[i] = max(sell[i-1], buy[i-1] + prices[i])

    其中buy[0] = -prices[0], buy[1] = max(-prices[0], -prices[1]), sell[0] = 0, sell[1] = max(0, prices[1] - prices[0])
    比如:
    prices:1, 2, 3, 0, 2
    buy: -1, -1, -1, 1, 1
    sell 0, 1, 2, 2, 3

public int maxProfit(int[] prices) {
        if(prices == null || prices.length <= 1) {
            return 0;
        }
        int len = prices.length;
        int[] buy = new int[len];
        int[] sell = new int[len];
        buy[0] = -prices[0];
        buy[1] = Math.max(-prices[0], -prices[1]);
        sell[0] = 0;
        sell[1] = Math.max(0, prices[1]-prices[0]);
        for(int i = 2; i < len; i++) {
            buy[i] = Math.max(buy[i-1], sell[i-2]-prices[i]);
            sell[i] = Math.max(sell[i-1], buy[i-1]+prices[i]);
        }
        return sell[len-1];
    }
基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值