20天拿下华为OD笔试之 【DP/贪心】2023Q1A-贪心的商人【闭着眼睛学数理化】全网注释最详细分类最全的华为OD真题题解

【DP/贪心】2023Q1A-贪心的商人

题目描述与示例

题目描述

商人经营一家店铺,有 number 种商品,由于仓库限制每件商品的最大持有数量是 item[index],每种商品的价格在每天是 item_price[item_index][day],通过对商品的买进和卖出获取利润,请给出商人在 days 天内能获取到的最大的利润;

注: 同一件商品可以反复买进和卖出;

输入描述

3     // 输入商品的数量 number
3     // 输入商人售货天数 days
4 5 6 // 输入仓库限制每件商品的最大持有数量是 item[index]
1 2 3 // 输入第一件商品每天的价格
4 3 2 // 输入第二件商品每天的价格
1 5 3 // 输入第三件商品每天的价格

输出描述

32     // 输出商人在这段时间内的最大利润

说明

根据输入的信息: number = 3days = 3item = [4,5,6]item_price = [[1,2,3],[4,3,2],[1,5,3]]

  • 针对第一件商品,商人在第一天的价格是 item_price[0][0] = 1 时买入 item[0]件,在第三天 item_price[0][2] = 3 的时候卖出,获利最大是 8
  • 针对第二件商品,不进行交易,获利最大是 0
  • 针对第三件商品,商人在第一天的价格是 item_price[2][0] = 1 时买入 item[2]件,在第二天 item_price[2][0] == 5 的时候卖出,获利最大是 24

因此这段时间商人能获取的最大利润是 8 + 24 = 32

示例一

输入

3
3
4 5 6
1 2 3
4 3 2
1 5 3

输出

32

示例二

输入

1

输出

0

解题思路

注意,本题的核心逻辑和LC122. 买卖股票的最佳时机II完全一致。

注意到各种商品之间是相互独立的,即第i件商品的买卖与第j件商品的买卖无关。因此对于每一种商品我们都可以单独计算其利润,再将利润加总即可。

又注意到对于某特定商品而言,存在关系总利润 = 数量 × 单件利润。故我们仅需计算某商品单件能取得的最大利润,再直接乘以每件商品的最大库存数number[i]即为该种商品能取得的总利润。

计算单件商品最大利润的核心代码完全无需修改,不管用贪心还是动态规划,假设我们已经成功定义了函数maxProfit(),那么上述逻辑整理为代码即

n = int(input())
days = int(input())
numbers = list(map(int, input().split()))

ans = 0
for i in range(n):
    prices = list(map(int, input().split()))
    ans += maxProfit(prices, days) * numbers[i]

print(ans)

代码

解法一

# 题目:2023Q1A-贪心的商人
# 分值:100
# 作者:闭着眼睛学数理化
# 算法:贪心
# 代码看不懂的地方,请直接在群上提问


# 计算某个特定商品能取得的最大利润的函数
# 和LeetCode122. 买卖股票的最佳时机II完全一致
def maxProfit(prices, days):
    # 最大利润初始为 0
    profit = 0

    # 从第 2 天开始(索引为 1)
    # 去查看当天是否需要采取【卖出】的操作
    for i in range(1, days):

        # 计算当天的股票价格与昨天的股票价格的差值
        tmp = prices[i] - prices[i - 1]

        # 如果发现当天的股票价格大于了昨天的股票价格
        # 那么在当天采取【卖出】操作可以带来正向收益,即产生利润
        # 于是完全可以卖出
        # 而这个利润就可以进行累加起来
        if tmp > 0:
            profit += tmp

        # 如果发现当天的股票价格小于了昨天的股票价格
        # 那么不能采取【卖出】操作,因为这会带来负向收益,即产生亏损
        # 导致总的利润值变小

    # 返回结果
    return profit

# 输入商品数量
n = int(input())
# 输入天数
days = int(input())
# 输入每种商品的最大数目
numbers = list(map(int, input().split()))

# 初始化答案变量
ans = 0
# 循环n次,输入每种商品在days天中的价格变化
for i in range(n):
    prices = list(map(int, input().split()))
    # maxProfit(prices, days)返回单件第i种商品能够取得的最大利润
    # 再乘上numbers[i]即为能够获得第i种商品能够获得的总利润
    ans += maxProfit(prices, days) * numbers[i]

print(ans)

时空复杂度

时间复杂度:O(NM)。需要循环N种商品,每次都要遍历M天来计算最大利润。

空间复杂度:O(1)。无需额外空间储存数据。

解法二

# 题目:2023Q1A-贪心的商人
# 分值:100
# 作者:闭着眼睛学数理化
# 算法:动态规划
# 代码看不懂的地方,请直接在群上提问


# 计算某个特定商品能取得的最大利润的函数
# 和LeetCode122. 买卖股票的最佳时机II完全一致
def maxProfit(prices, days):
    pass

# 输入商品数量
n = int(input())
# 输入天数
days = int(input())
# 输入每种商品的最大数目
numbers = list(map(int, input().split()))

# 初始化答案变量
ans = 0
# 循环n次,输入每种商品在days天中的价格变化
for i in range(n):
    prices = list(map(int, input().split()))
    # maxProfit(prices, days)返回单件第i种商品能够取得的最大利润
    # 再乘上numbers[i]即为能够获得第i种商品能够获得的总利润
    ans += maxProfit(prices, days) * numbers[i]

print(ans)

时空复杂度

时间复杂度:O(NM)

空间复杂度:O(N)

华为OD算法冲刺训练

  • 华为OD算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 30+天陪伴式学习,20+直播课时,300+动画图解视频,200+LeetCode经典题,100+华为OD真题,还有简历修改与模拟面试将为你解锁

  • 可查看链接 OD算法冲刺训练课程表 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 sheepvipvip了解更多

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值