【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 = 3
,days = 3
,item = [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
了解更多