Skip to content

Commit 97a3e0a

Browse files
author
robot
committed
feat: $1770
1 parent bc03fd1 commit 97a3e0a

File tree

3 files changed

+174
-1
lines changed

3 files changed

+174
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,8 @@ leetcode 题解,记录自己的 leetcode 解题之路。
412412
- [1631. 最小体力消耗路径](./problems/1631.path-with-minimum-effort.md)
413413
- [1658. 将 x 减到 0 的最小操作数](./problems/1658.minimum-operations-to-reduce-x-to-zero.md)
414414
- [1697. 检查边长度限制的路径是否存在](./problems/1697.checking-existence-of-edge-length-limited-paths.md)
415-
- [1737. 满足三条件之一需改变的最少字符数](./problems/1737.change-minimum-characters-to-satisfy-one-of-three-conditions.md)
415+
- [1737. 满足三条件之一需改变的最少字符数](./problems/1737.change-minimum-characters-to-satisfy-one-of-three-conditions.md) 👍
416+
- [1770. 执行乘法运算的最大分数](./problems/1770.maximum-score-from-performing-multiplication-operations.md) 👍 91
416417
- [1834. 单线程 CPU](./problems/1834.single-threaded-cpu.md)
417418
- [1899. 合并若干三元组以形成目标三元组](./problems/1899.merge-triplets-to-form-target-triplet.md) 👍
418419
- [1904. 你完成的完整对局数](./problems/1904.the-number-of-full-rounds-you-have-played.md)

SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@
261261
- [1658. 将 x 减到 0 的最小操作数](./problems/1658.minimum-operations-to-reduce-x-to-zero.md)
262262
- [1697. 检查边长度限制的路径是否存在](./problems/1697.checking-existence-of-edge-length-limited-paths.md)
263263
- [1737. 满足三条件之一需改变的最少字符数](./problems/1737.change-minimum-characters-to-satisfy-one-of-three-conditions.md) 👍
264+
- [1770. 执行乘法运算的最大分数](./problems/1770.maximum-score-from-performing-multiplication-operations.md)👍 91
264265
- [1834. 单线程 CPU](./problems/1834.single-threaded-cpu.md)
265266
- [1899. 合并若干三元组以形成目标三元组](./problems/1899.merge-triplets-to-form-target-triplet.md) 👍
266267
- [1904. 你完成的完整对局数](./problems/1904.the-number-of-full-rounds-you-have-played.md)
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
## 题目地址(1770. 执行乘法运算的最大分数)
2+
3+
https://leetcode.cn/problems/maximum-score-from-performing-multiplication-operations/
4+
5+
## 题目描述
6+
7+
```
8+
给你两个长度分别 n 和 m 的整数数组 nums 和 multipliers ,其中 n >= m ,数组下标 从 1 开始 计数。
9+
10+
初始时,你的分数为 0 。你需要执行恰好 m 步操作。在第 i 步操作(从 1 开始 计数)中,需要:
11+
12+
选择数组 nums 开头处或者末尾处 的整数 x 。
13+
你获得 multipliers[i] * x 分,并累加到你的分数中。
14+
将 x 从数组 nums 中移除。
15+
16+
在执行 m 步操作后,返回 最大 分数。
17+
18+
 
19+
20+
示例 1:
21+
22+
输入:nums = [1,2,3], multipliers = [3,2,1]
23+
输出:14
24+
解释:一种最优解决方案如下:
25+
- 选择末尾处的整数 3 ,[1,2,3] ,得 3 * 3 = 9 分,累加到分数中。
26+
- 选择末尾处的整数 2 ,[1,2] ,得 2 * 2 = 4 分,累加到分数中。
27+
- 选择末尾处的整数 1 ,[1] ,得 1 * 1 = 1 分,累加到分数中。
28+
总分数为 9 + 4 + 1 = 14 。
29+
30+
示例 2:
31+
32+
输入:nums = [-5,-3,-3,-2,7,1], multipliers = [-10,-5,3,4,6]
33+
输出:102
34+
解释:一种最优解决方案如下:
35+
- 选择开头处的整数 -5 ,[-5,-3,-3,-2,7,1] ,得 -5 * -10 = 50 分,累加到分数中。
36+
- 选择开头处的整数 -3 ,[-3,-3,-2,7,1] ,得 -3 * -5 = 15 分,累加到分数中。
37+
- 选择开头处的整数 -3 ,[-3,-2,7,1] ,得 -3 * 3 = -9 分,累加到分数中。
38+
- 选择末尾处的整数 1 ,[-2,7,1] ,得 1 * 4 = 4 分,累加到分数中。
39+
- 选择末尾处的整数 7 ,[-2,7] ,得 7 * 6 = 42 分,累加到分数中。
40+
总分数为 50 + 15 - 9 + 4 + 42 = 102 。
41+
42+
43+
 
44+
45+
提示:
46+
47+
n == nums.length
48+
m == multipliers.length
49+
1 <= m <= 103
50+
m <= n <= 105
51+
-1000 <= nums[i], multipliers[i] <= 1000
52+
```
53+
54+
## 前置知识
55+
56+
- 动态规划
57+
- 区间动态规划
58+
59+
## 公司
60+
61+
- 暂无
62+
63+
## 思路
64+
65+
这是一个典型的区间 DP 问题。
66+
67+
直接套用区间 DP 的公,定义 DP[i][j] 为考虑区间 nums[i:j] 的情况下, 所能获得的最大分数。
68+
69+
那么我们有两个选择, 取左端点或者取右端点,这两种选择取最大值即可。同时需要一个变量记录当前是第几步操作, 以便知道要乘以多少。
70+
71+
这样 dp[i][j][steps] 就表示考虑区间 nums[i:j] 的情况下当前是第 steps 步, 所能获得的最大分数。
72+
73+
```py
74+
class Solution:
75+
def maximumScore(self, nums: List[int], multipliers: List[int]) -> int:
76+
@cache
77+
def dp(i, j, steps):
78+
if steps == len(multipliers): return 0
79+
return max(dp(i + 1, j, steps + 1) + multipliers[steps] * nums[i], dp(i, j - 1, steps + 1) + multipliers[steps] * nums[j])
80+
return dp(0, len(nums) - 1, 0)
81+
```
82+
83+
上面代码非常好写,复杂度为 $O(m*n^2)$但是会严重超时。代入题目中的数据 m 为 10^3, n 为 10 ^ 5,那么整体就是 $10^13$, 远远大于 $10^7$ 这个临界值。
84+
85+
注意到 steps 其实可以根据 i 和 j 推导出来。因为每一步我们必定要选择一次,这是关键。那么我们当前选择了多少就可以根据 i 和 j 推导出来, 这样就可以降低到二维 dp[i][j]。代码:
86+
87+
```py
88+
class Solution:
89+
def maximumScore(self, nums: List[int], multipliers: List[int]) -> int:
90+
@cache
91+
def dp(i, j):
92+
steps = len(nums) - (j - i + 1)
93+
if steps == len(multipliers): return 0
94+
return max(dp(i + 1, j) + multipliers[steps] * nums[i], dp(i, j - 1,) + multipliers[steps] * nums[j])
95+
return dp(0, len(nums) - 1)
96+
```
97+
98+
不过代入后还是远远大于 $10^7$ 这个临界值。
99+
100+
小技巧,下面的代码可以通过,不过也不推荐。
101+
102+
```py
103+
class Solution:
104+
def maximumScore(self, nums: List[int], multipliers: List[int]) -> int:
105+
@cache
106+
def dp(i, j):
107+
steps = len(nums) - (j - i + 1)
108+
if steps == len(multipliers): return 0
109+
return max(dp(i + 1, j) + multipliers[steps] * nums[i], dp(i, j - 1,) + multipliers[steps] * nums[j])
110+
ans = dp(0, len(nums) - 1)
111+
dp.cache_clear()
112+
return ans
113+
```
114+
115+
这里要使用到一种技巧 - 维度选择。
116+
117+
我们可以换一种状态定义方式,即思考 mutlipiers, 因为它的数据量小(题目给的是 10 ^ 3)。
118+
119+
实际上,我们可以定义 dp[i][j] 为选择 nums 前 i 项目和 nums 后 j 项目可以获得的最大分数(题目限制了只能取左右两端)。但是注意到 i 和 j 一定是要小于 m 的, 因为不妨直接枚举到 m 即可, 而不需要枚举到 n。
120+
121+
显然这种方式枚举的时间复杂度为 $O(m^2)$,代入题目大概是 $10^6$ , 小于临界值 $10^7$。
122+
123+
## 关键点
124+
125+
- 维度选择
126+
- 降维
127+
128+
## 代码
129+
130+
- 语言支持:Python3
131+
132+
Python3 Code:
133+
134+
```python
135+
136+
class Solution:
137+
def maximumScore(self, nums: List[int], multipliers: List[int]) -> int:
138+
n,m=len(nums),len(multipliers)
139+
dp=[[float('-inf')]*(m+1) for _ in range(m+1)]
140+
dp[0][0]=0
141+
ans=float('-inf')
142+
for i in range(1,m+1): # 枚举长度
143+
for l in range(i+1): # 枚举左侧取了 l 个
144+
r = i - l # 右侧取的就是总数 - 左边取的
145+
dp[l][r]=max(dp[l][r],dp[l-1][r]+nums[l-1]*multipliers[i-1], dp[l][r-1]+nums[-r]*multipliers[i-1])
146+
if i == m: ans=max(ans,dp[l][r])
147+
return ans
148+
149+
150+
```
151+
152+
**复杂度分析**
153+
154+
令 n 为数组长度。
155+
156+
- 时间复杂度:$O(n^2)$
157+
- 空间复杂度:$O(n^2)$
158+
159+
> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。
160+
161+
力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/),这样就会第一时间收到我的动态啦~
162+
163+
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
164+
165+
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
166+
167+
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg)
168+
169+
## 其他
170+
171+
大家也可以看下[力扣国际站的官方题解](https://leetcode.com/problems/maximum-score-from-performing-multiplication-operations/solution/)

0 commit comments

Comments
 (0)