64
64
65
65
** 方法一:记忆化搜索**
66
66
67
+ 我们设计一个函数 $dfs(i)$,表示从第 $i$ 个问题开始解决,能够获得的最高分数。那么答案就是 $dfs(0)$。
68
+
69
+ 函数 $dfs(i)$ 的计算方式如下:
70
+
71
+ - 如果 $i \geq n$,表示已经解决完所有问题,返回 $0$;
72
+ - 否则,设第 $i$ 个问题的分数为 $p$,需要跳过的问题数为 $b$,那么 $dfs(i) = \max(p + dfs(i + b + 1), dfs(i + 1))$。
73
+
74
+ 为了避免重复计算,我们可以使用记忆化搜索的方法,用一个数组 $f$ 记录所有已经计算过的 $dfs(i)$ 的值。
75
+
76
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是问题的数量。
77
+
78
+ ** 方法二:动态规划**
79
+
80
+ 我们定义 $f[ i] $ 表示从第 $i$ 个问题开始解决,能够获得的最高分数。那么答案就是 $f[ 0] $。
81
+
82
+ 考虑 $f[ i] $,第 $i$ 个问题的分数为 $p$,需要跳过的问题数为 $b$。如果我们解决了第 $i$ 个问题,那么接下来我们需要解决 $b$ 个问题,因此 $f[ i] = p + f[ i + b + 1] $。如果我们跳过了第 $i$ 个问题,那么接下来我们从第 $i + 1$ 个问题开始解决,因此 $f[ i] = f[ i + 1] $。两者取最大值即可。状态转移方程如下:
83
+
84
+ $$
85
+ f[i] = \max(p + f[i + b + 1], f[i + 1])
86
+ $$
87
+
88
+ 我们从后往前计算 $f$ 的值,最后返回 $f[ 0] $ 即可。
89
+
90
+ 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是问题的数量。
91
+
67
92
<!-- tabs:start -->
68
93
69
94
### ** Python3**
74
99
class Solution :
75
100
def mostPoints (self , questions : List[List[int ]]) -> int :
76
101
@cache
77
- def dfs (i ) :
102
+ def dfs (i : int ) -> int :
78
103
if i >= len (questions):
79
104
return 0
80
- return max (questions[i][0 ] + dfs(i + questions[i][1 ] + 1 ), dfs(i + 1 ))
105
+ p, b = questions[i]
106
+ return max (p + dfs(i + b + 1 ), dfs(i + 1 ))
81
107
82
108
return dfs(0 )
83
109
```
84
110
111
+ ``` python
112
+ class Solution :
113
+ def mostPoints (self , questions : List[List[int ]]) -> int :
114
+ n = len (questions)
115
+ f = [0 ] * (n + 1 )
116
+ for i in range (n - 1 , - 1 , - 1 ):
117
+ p, b = questions[i]
118
+ j = i + b + 1
119
+ f[i] = max (f[i + 1 ], p + (0 if j > n else f[j]))
120
+ return f[0 ]
121
+ ```
122
+
85
123
### ** Java**
86
124
87
125
<!-- 这里可写当前语言的特殊实现逻辑 -->
88
126
89
127
``` java
90
128
class Solution {
91
- private long [] memo;
129
+ private int n;
130
+ private Long [] f;
92
131
private int [][] questions;
93
132
94
133
public long mostPoints (int [][] questions ) {
134
+ n = questions. length;
135
+ f = new Long [n];
95
136
this . questions = questions;
96
- memo = new long [questions. length];
97
- Arrays . fill(memo, - 1 );
98
137
return dfs(0 );
99
138
}
100
139
101
140
private long dfs (int i ) {
102
- if (i >= questions . length ) {
141
+ if (i >= n ) {
103
142
return 0 ;
104
143
}
105
- if (memo[i] != - 1 ) {
106
- return memo[i];
144
+ if (f[i] != null ) {
145
+ return f[i];
146
+ }
147
+ int p = questions[i][0 ], b = questions[i][1 ];
148
+ return f[i] = Math . max(p + dfs(i + b + 1 ), dfs(i + 1 ));
149
+ }
150
+ }
151
+ ```
152
+
153
+ ``` java
154
+ class Solution {
155
+ public long mostPoints (int [][] questions ) {
156
+ int n = questions. length;
157
+ long [] f = new long [n + 1 ];
158
+ for (int i = n - 1 ; i >= 0 ; -- i) {
159
+ int p = questions[i][0 ], b = questions[i][1 ];
160
+ int j = i + b + 1 ;
161
+ f[i] = Math . max(f[i + 1 ], p + (j > n ? 0 : f[j]));
107
162
}
108
- long ans = Math . max(questions[i][0 ] + dfs(i + questions[i][1 ] + 1 ), dfs(i + 1 ));
109
- memo[i] = ans;
110
- return ans;
163
+ return f[0 ];
111
164
}
112
165
}
113
166
```
@@ -118,16 +171,37 @@ class Solution {
118
171
class Solution {
119
172
public:
120
173
long long mostPoints(vector<vector<int >>& questions) {
121
- vector<long long > memo(questions.size(), -1);
122
- return dfs(0, questions, memo);
174
+ int n = questions.size();
175
+ long long f[ n] ;
176
+ memset(f, 0, sizeof(f));
177
+ function<long long(int)> dfs = [ &] (int i) -> long long {
178
+ if (i >= n) {
179
+ return 0;
180
+ }
181
+ if (f[ i] ) {
182
+ return f[ i] ;
183
+ }
184
+ int p = questions[ i] [ 0 ] , b = questions[ i] [ 1 ] ;
185
+ return f[ i] = max(p + dfs(i + b + 1), dfs(i + 1));
186
+ };
187
+ return dfs(0);
123
188
}
189
+ };
190
+ ```
124
191
125
- long long dfs(int i, vector<vector<int>>& questions, vector<long long>& memo) {
126
- if (i >= questions.size()) return 0;
127
- if (memo[i] != -1) return memo[i];
128
- long long ans = max(questions[i][0] + dfs(i + questions[i][1] + 1, questions, memo), dfs(i + 1, questions, memo));
129
- memo[i] = ans;
130
- return ans;
192
+ ```cpp
193
+ class Solution {
194
+ public:
195
+ long long mostPoints(vector<vector<int>>& questions) {
196
+ int n = questions.size();
197
+ long long f[n + 1];
198
+ memset(f, 0, sizeof(f));
199
+ for (int i = n - 1; ~i; --i) {
200
+ int p = questions[i][0], b = questions[i][1];
201
+ int j = i + b + 1;
202
+ f[i] = max(f[i + 1], p + (j > n ? 0 : f[j]));
203
+ }
204
+ return f[0];
131
205
}
132
206
};
133
207
```
@@ -137,39 +211,83 @@ public:
137
211
``` go
138
212
func mostPoints (questions [][]int ) int64 {
139
213
n := len (questions)
140
- memo := make ([]int , n)
141
- for i := range memo {
142
- memo[i] = -1
143
- }
144
- var dfs func (i int ) int
145
- dfs = func (i int ) int {
214
+ f := make ([]int64 , n)
215
+ var dfs func (int ) int64
216
+ dfs = func (i int ) int64 {
146
217
if i >= n {
147
218
return 0
148
219
}
149
- if memo [i] != - 1 {
150
- return memo [i]
220
+ if f [i] > 0 {
221
+ return f [i]
151
222
}
152
- ans := max ( questions[i][0 ]+ dfs (i+ questions[i][1 ]+ 1 ), dfs (i+ 1 ))
153
- memo [i] = ans
154
- return ans
223
+ p , b := questions[i][0 ], questions[i][1 ]
224
+ f [i] = max ( int64 (p)+ dfs (i+b+ 1 ), dfs (i+ 1 ))
225
+ return f[i]
155
226
}
156
- return int64 ( dfs (0 ) )
227
+ return dfs (0 )
157
228
}
158
229
159
- func max (a , b int ) int {
230
+ func max (a , b int64 ) int64 {
160
231
if a > b {
161
232
return a
162
233
}
163
234
return b
164
235
}
165
236
```
166
237
167
- ### ** TypeScript**
238
+ ``` go
239
+ func mostPoints (questions [][]int ) int64 {
240
+ n := len (questions)
241
+ f := make ([]int64 , n+1 )
242
+ for i := n - 1 ; i >= 0 ; i-- {
243
+ p := int64 (questions[i][0 ])
244
+ if j := i + questions[i][1 ] + 1 ; j <= n {
245
+ p += f[j]
246
+ }
247
+ f[i] = max (f[i+1 ], p)
248
+ }
249
+ return f[0 ]
250
+ }
168
251
169
- <!-- 这里可写当前语言的特殊实现逻辑 -->
252
+ func max (a , b int64 ) int64 {
253
+ if a > b {
254
+ return a
255
+ }
256
+ return b
257
+ }
258
+ ```
259
+
260
+ ### ** TypeScript**
170
261
171
262
``` ts
263
+ function mostPoints(questions : number [][]): number {
264
+ const n = questions .length ;
265
+ const f = Array (n ).fill (0 );
266
+ const dfs = (i : number ): number => {
267
+ if (i >= n ) {
268
+ return 0 ;
269
+ }
270
+ if (f [i ] > 0 ) {
271
+ return f [i ];
272
+ }
273
+ const [p, b] = questions [i ];
274
+ return (f [i ] = Math .max (p + dfs (i + b + 1 ), dfs (i + 1 )));
275
+ };
276
+ return dfs (0 );
277
+ }
278
+ ```
172
279
280
+ ``` ts
281
+ function mostPoints(questions : number [][]): number {
282
+ const n = questions .length ;
283
+ const f = Array (n + 1 ).fill (0 );
284
+ for (let i = n - 1 ; i >= 0 ; -- i ) {
285
+ const [p, b] = questions [i ];
286
+ const j = i + b + 1 ;
287
+ f [i ] = Math .max (f [i + 1 ], p + (j > n ? 0 : f [j ]));
288
+ }
289
+ return f [0 ];
290
+ }
173
291
```
174
292
175
293
### ** ...**
0 commit comments