Skip to content

Commit f05f20b

Browse files
committed
feat: add solutions to lc problem: No.1626
No.1626.Best Team With No Conflicts
1 parent e8c89ed commit f05f20b

File tree

7 files changed

+610
-161
lines changed

7 files changed

+610
-161
lines changed

solution/1600-1699/1626.Best Team With No Conflicts/README.md

+245-53
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,29 @@
4949

5050
<!-- 这里可写通用的实现逻辑 -->
5151

52-
**方法一:动态规划**
52+
**方法一:排序 + 动态规划**
5353

54-
最长上升子序列模型
54+
我们可以将球员按照分数从小到大排序,如果分数相同,则按照年龄从小到大排序
5555

56-
将所有球员先按照年龄从小到大排序(年龄相同,则按照分数从小到大排),然后在分数数组中求解最长上升子序列和的最大值即可。最长上升子序列朴素做法,时间复杂度 $O(n^2)$
56+
接下来,使用动态规划求解
5757

58-
类似题型:洛谷 “[P2782 友好城市](https://www.luogu.com.cn/problem/P2782)”。
58+
我们定义 $f[i]$ 表示以排序后的第 $i$ 个球员作为最后一个球员的最大得分,那么答案就是 $\max_{0 \leq i < n} f[i]$。
59+
60+
对于 $f[i]$,我们可以枚举 $0 \leq j \lt i$,如果第 $i$ 个球员的年龄大于等于第 $j$ 个球员的年龄,则 $f[i]$ 可以从 $f[j]$ 转移而来,转移方程为 $f[i] = \max(f[i], f[j])$。然后我们将第 $i$ 个球员的分数加到 $f[i]$ 中,即 $f[i] += scores[i]$。
61+
62+
最后,我们返回 $\max_{0 \leq i < n} f[i]$ 即可。
63+
64+
时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为球员的数量。
65+
66+
**方法二:排序 + 树状数组**
67+
68+
与方法一类似,我们可以将球员按照分数从小到大排序,如果分数相同,则按照年龄从小到大排序。
69+
70+
接下来,我们使用树状数组维护不超过当前球员年龄的球员的最大得分。每一次,我们只需要在 $O(\log m)$ 的时间内找出不超过当前球员年龄的球员的最大得分,然后将当前球员的分数加到该得分上,即可更新当前球员年龄的最大得分。
71+
72+
最后,我们返回得分的最大值即可。
73+
74+
时间复杂度 $O(n \times (\log n + \log m))$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别为球员的数量和球员的年龄的最大值。
5975

6076
<!-- tabs:start -->
6177

@@ -66,15 +82,43 @@
6682
```python
6783
class Solution:
6884
def bestTeamScore(self, scores: List[int], ages: List[int]) -> int:
69-
nums = list(zip(ages, scores))
70-
nums.sort()
71-
n = len(nums)
72-
dp = [num[1] for num in nums]
73-
for i in range(n):
85+
arr = sorted(zip(scores, ages))
86+
n = len(arr)
87+
f = [0] * n
88+
for i, (score, age) in enumerate(arr):
7489
for j in range(i):
75-
if nums[i][1] >= nums[j][1]:
76-
dp[i] = max(dp[i], dp[j] + nums[i][1])
77-
return max(dp)
90+
if age >= arr[j][1]:
91+
f[i] = max(f[i], f[j])
92+
f[i] += score
93+
return max(f)
94+
```
95+
96+
```python
97+
class BinaryIndexedTree:
98+
def __init__(self, n):
99+
self.n = n
100+
self.c = [0] * (n + 1)
101+
102+
def update(self, x, val):
103+
while x <= self.n:
104+
self.c[x] = max(self.c[x], val)
105+
x += x & -x
106+
107+
def query(self, x):
108+
s = 0
109+
while x:
110+
s = max(s, self.c[x])
111+
x -= x & -x
112+
return s
113+
114+
115+
class Solution:
116+
def bestTeamScore(self, scores: List[int], ages: List[int]) -> int:
117+
m = max(ages)
118+
tree = BinaryIndexedTree(m)
119+
for score, age in sorted(zip(scores, ages)):
120+
tree.update(age, score + tree.query(age))
121+
return tree.query(m)
78122
```
79123

80124
### **Java**
@@ -85,77 +129,225 @@ class Solution:
85129
class Solution {
86130
public int bestTeamScore(int[] scores, int[] ages) {
87131
int n = ages.length;
88-
int[][] nums = new int[n][2];
132+
int[][] arr = new int[n][2];
89133
for (int i = 0; i < n; ++i) {
90-
nums[i] = new int[] {ages[i], scores[i]};
134+
arr[i] = new int[] {scores[i], ages[i]};
91135
}
92-
Arrays.sort(nums, (a, b) -> { return a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]; });
93-
int[] dp = new int[n];
136+
Arrays.sort(arr, (a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
137+
int[] f = new int[n];
94138
int ans = 0;
95139
for (int i = 0; i < n; ++i) {
96-
dp[i] = nums[i][1];
97140
for (int j = 0; j < i; ++j) {
98-
if (nums[i][1] >= nums[j][1]) {
99-
dp[i] = Math.max(dp[i], dp[j] + nums[i][1]);
141+
if (arr[i][1] >= arr[j][1]) {
142+
f[i] = Math.max(f[i], f[j]);
100143
}
101144
}
102-
ans = Math.max(ans, dp[i]);
145+
f[i] += arr[i][0];
146+
ans = Math.max(ans, f[i]);
103147
}
104148
return ans;
105149
}
106150
}
107151
```
108152

153+
```java
154+
class BinaryIndexedTree {
155+
private int n;
156+
private int[] c;
157+
158+
public BinaryIndexedTree(int n) {
159+
this.n = n;
160+
c = new int[n + 1];
161+
}
162+
163+
public void update(int x, int val) {
164+
while (x <= n) {
165+
c[x] = Math.max(c[x], val);
166+
x += x & -x;
167+
}
168+
}
169+
170+
public int query(int x) {
171+
int s = 0;
172+
while (x > 0) {
173+
s = Math.max(s, c[x]);
174+
x -= x & -x;
175+
}
176+
return s;
177+
}
178+
}
179+
180+
181+
class Solution {
182+
public int bestTeamScore(int[] scores, int[] ages) {
183+
int n = ages.length;
184+
int[][] arr = new int[n][2];
185+
for (int i = 0; i < n; ++i) {
186+
arr[i] = new int[] {scores[i], ages[i]};
187+
}
188+
Arrays.sort(arr, (a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
189+
int m = 0;
190+
for (int age : ages) {
191+
m = Math.max(m, age);
192+
}
193+
BinaryIndexedTree tree = new BinaryIndexedTree(m);
194+
for (int[] x : arr) {
195+
tree.update(x[1], x[0] + tree.query(x[1]));
196+
}
197+
return tree.query(m);
198+
}
199+
}
200+
```
201+
109202
### **C++**
110203

111204
```cpp
112205
class Solution {
113206
public:
114207
int bestTeamScore(vector<int>& scores, vector<int>& ages) {
115208
int n = ages.size();
116-
vector<vector<int>> nums(n);
117-
for (int i = 0; i < n; ++i) nums[i] = {ages[i], scores[i]};
118-
sort(nums.begin(), nums.end());
119-
vector<int> dp(n);
209+
vector<pair<int, int>> arr(n);
210+
for (int i = 0; i < n; ++i) {
211+
arr[i] = {scores[i], ages[i]};
212+
}
213+
sort(arr.begin(), arr.end());
214+
vector<int> f(n);
120215
for (int i = 0; i < n; ++i) {
121-
dp[i] = nums[i][1];
122216
for (int j = 0; j < i; ++j) {
123-
if (nums[i][1] >= nums[j][1])
124-
dp[i] = max(dp[i], dp[j] + nums[i][1]);
217+
if (arr[i].second >= arr[j].second) {
218+
f[i] = max(f[i], f[j]);
219+
}
125220
}
221+
f[i] += arr[i].first;
126222
}
127-
return *max_element(dp.begin(), dp.end());
223+
return *max_element(f.begin(), f.end());
224+
}
225+
};
226+
```
227+
228+
```cpp
229+
class BinaryIndexedTree {
230+
public:
231+
BinaryIndexedTree(int _n) : n(_n), c(_n + 1) {}
232+
233+
void update(int x, int val) {
234+
while (x <= n) {
235+
c[x] = max(c[x], val);
236+
x += x & -x;
237+
}
238+
}
239+
240+
int query(int x) {
241+
int s = 0;
242+
while (x) {
243+
s = max(s, c[x]);
244+
x -= x & -x;
245+
}
246+
return s;
247+
}
248+
249+
private:
250+
int n;
251+
vector<int> c;
252+
};
253+
254+
class Solution {
255+
public:
256+
int bestTeamScore(vector<int>& scores, vector<int>& ages) {
257+
int n = ages.size();
258+
vector<pair<int, int>> arr(n);
259+
for (int i = 0; i < n; ++i) {
260+
arr[i] = {scores[i], ages[i]};
261+
}
262+
sort(arr.begin(), arr.end());
263+
int m = *max_element(ages.begin(), ages.end());
264+
BinaryIndexedTree tree(m);
265+
for (auto& [score, age] : arr) {
266+
tree.update(age, score + tree.query(age));
267+
}
268+
return tree.query(m);
128269
}
129270
};
130271
```
131272

132273
### **Go**
133274

134275
```go
135-
func bestTeamScore(scores []int, ages []int) int {
276+
func bestTeamScore(scores []int, ages []int) (ans int) {
136277
n := len(ages)
137-
nums := make([][]int, n)
138-
for i, age := range ages {
139-
nums[i] = []int{age, scores[i]}
278+
arr := make([][2]int, n)
279+
for i := range ages {
280+
arr[i] = [2]int{scores[i], ages[i]}
140281
}
141-
sort.Slice(nums, func(i, j int) bool {
142-
if nums[i][0] != nums[j][0] {
143-
return nums[i][0] < nums[j][0]
144-
}
145-
return nums[i][1] < nums[j][1]
282+
sort.Slice(arr, func(i, j int) bool {
283+
a, b := arr[i], arr[j]
284+
return a[0] < b[0] || a[0] == b[0] && a[1] < b[1]
146285
})
147-
dp := make([]int, n)
148-
ans := 0
149-
for i, num := range nums {
150-
dp[i] = num[1]
286+
f := make([]int, n)
287+
for i := range arr {
151288
for j := 0; j < i; j++ {
152-
if num[1] >= nums[j][1] {
153-
dp[i] = max(dp[i], dp[j]+num[1])
289+
if arr[i][1] >= arr[j][1] {
290+
f[i] = max(f[i], f[j])
154291
}
155292
}
156-
ans = max(ans, dp[i])
293+
f[i] += arr[i][0]
294+
ans = max(ans, f[i])
295+
}
296+
return
297+
}
298+
299+
func max(a, b int) int {
300+
if a > b {
301+
return a
302+
}
303+
return b
304+
}
305+
```
306+
307+
```go
308+
type BinaryIndexedTree struct {
309+
n int
310+
c []int
311+
}
312+
313+
func newBinaryIndexedTree(n int) *BinaryIndexedTree {
314+
c := make([]int, n+1)
315+
return &BinaryIndexedTree{n, c}
316+
}
317+
318+
func (this *BinaryIndexedTree) update(x, val int) {
319+
for x <= this.n {
320+
this.c[x] = max(this.c[x], val)
321+
x += x & -x
322+
}
323+
}
324+
325+
func (this *BinaryIndexedTree) query(x int) int {
326+
s := 0
327+
for x > 0 {
328+
s = max(s, this.c[x])
329+
x -= x & -x
330+
}
331+
return s
332+
}
333+
334+
func bestTeamScore(scores []int, ages []int) int {
335+
n := len(ages)
336+
arr := make([][2]int, n)
337+
m := 0
338+
for i, age := range ages {
339+
m = max(m, age)
340+
arr[i] = [2]int{scores[i], age}
341+
}
342+
sort.Slice(arr, func(i, j int) bool {
343+
a, b := arr[i], arr[j]
344+
return a[0] < b[0] || a[0] == b[0] && a[1] < b[1]
345+
})
346+
tree := newBinaryIndexedTree(m)
347+
for _, x := range arr {
348+
tree.update(x[1], x[0]+tree.query(x[1]))
157349
}
158-
return ans
350+
return tree.query(m)
159351
}
160352

161353
func max(a, b int) int {
@@ -175,19 +367,19 @@ func max(a, b int) int {
175367
* @return {number}
176368
*/
177369
var bestTeamScore = function (scores, ages) {
178-
const nums = ages.map((age, i) => [age, scores[i]]);
179-
nums.sort((a, b) => (a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]));
180-
const n = nums.length;
181-
let dp = new Array(n);
370+
const arr = ages.map((age, i) => [age, scores[i]]);
371+
arr.sort((a, b) => (a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]));
372+
const n = arr.length;
373+
const f = new Array(n).fill(0);
182374
let ans = 0;
183375
for (let i = 0; i < n; ++i) {
184-
dp[i] = nums[i][1];
185376
for (let j = 0; j < i; ++j) {
186-
if (nums[i][1] >= nums[j][1]) {
187-
dp[i] = Math.max(dp[i], dp[j] + nums[i][1]);
377+
if (arr[i][1] >= arr[j][1]) {
378+
f[i] = Math.max(f[i], f[j]);
188379
}
189380
}
190-
ans = Math.max(ans, dp[i]);
381+
f[i] += arr[i][1];
382+
ans = Math.max(ans, f[i]);
191383
}
192384
return ans;
193385
};

0 commit comments

Comments
 (0)