diff --git a/solution/3400-3499/3470.Permutations IV/README.md b/solution/3400-3499/3470.Permutations IV/README.md index f5bb6d3b42b01..7e7819b378d0d 100644 --- a/solution/3400-3499/3470.Permutations IV/README.md +++ b/solution/3400-3499/3470.Permutations IV/README.md @@ -6,7 +6,7 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3470.Pe -# [3470. 排列 IV](https://leetcode.cn/problems/permutations-iv) +# [3470. 全排列 IV](https://leetcode.cn/problems/permutations-iv) [English Version](/solution/3400-3499/3470.Permutations%20IV/README_EN.md) diff --git a/solution/3400-3499/3475.DNA Pattern Recognition/README.md b/solution/3400-3499/3475.DNA Pattern Recognition/README.md index d81a4f888be46..bb6aef3570cb7 100644 --- a/solution/3400-3499/3475.DNA Pattern Recognition/README.md +++ b/solution/3400-3499/3475.DNA Pattern Recognition/README.md @@ -8,7 +8,7 @@ tags: -# [3475. DNA Pattern Recognition](https://leetcode.cn/problems/dna-pattern-recognition) +# [3475. DNA 模式识别](https://leetcode.cn/problems/dna-pattern-recognition) [English Version](/solution/3400-3499/3475.DNA%20Pattern%20Recognition/README_EN.md) @@ -16,7 +16,7 @@ tags: -

Table: Samples

+

表:Samples

 +----------------+---------+
@@ -26,30 +26,31 @@ tags:
 | dna_sequence   | varchar |
 | species        | varchar |
 +----------------+---------+
-sample_id is the unique key for this table.
-Each row contains a DNA sequence represented as a string of characters (A, T, G, C) and the species it was collected from.
+sample_id 是这张表的唯一主键。
+每一行包含一个 DNA 序列以一个字符(A,T,G,C)组成的字符串表示以及它所采集自的物种。
 
-

Biologists are studying basic patterns in DNA sequences. Write a solution to identify sample_id with the following patterns:

+

生物学家正在研究 DNA 序列中的基本模式。编写一个解决方案以识别具有以下模式的 sample_id

-

Return the result table ordered by sample_id in ascending order.

+

返回结果表以 sample_id 升序 排序

-

The result format is in the following example.

+

结果格式如下所示。

 

-

Example:

+ +

示例:

-

Input:

+

输入:

-

Samples table:

+

Samples 表:

 +-----------+------------------+-----------+
@@ -65,7 +66,7 @@ Each row contains a DNA sequence represented as a string of characters (A, T, G,
 +-----------+------------------+-----------+
 
-

Output:

+

输出:

 +-----------+------------------+-------------+-------------+------------+------------+------------+
@@ -81,69 +82,69 @@ Each row contains a DNA sequence represented as a string of characters (A, T, G,
 +-----------+------------------+-------------+-------------+------------+------------+------------+
 
-

Explanation:

+

解释:

-

Note:

+

注意:

diff --git a/solution/3400-3499/3476.Maximize Profit from Task Assignment/README.md b/solution/3400-3499/3476.Maximize Profit from Task Assignment/README.md new file mode 100644 index 0000000000000..9ae83f16111a0 --- /dev/null +++ b/solution/3400-3499/3476.Maximize Profit from Task Assignment/README.md @@ -0,0 +1,260 @@ +--- +comments: true +difficulty: 中等 +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3476.Maximize%20Profit%20from%20Task%20Assignment/README.md +--- + + + +# [3476. Maximize Profit from Task Assignment 🔒](https://leetcode.cn/problems/maximize-profit-from-task-assignment) + +[English Version](/solution/3400-3499/3476.Maximize%20Profit%20from%20Task%20Assignment/README_EN.md) + +## 题目描述 + + + +

You are given an integer array workers, where workers[i] represents the skill level of the ith worker. You are also given a 2D integer array tasks, where:

+ + + +

Each worker can complete at most one task, and they can only take a task if their skill level is equal to the task's skill requirement. An additional worker joins today who can take up any task, regardless of the skill requirement.

+ +

Return the maximum total profit that can be earned by optimally assigning the tasks to the workers.

+ +

 

+

Example 1:

+ +
+

Input: workers = [1,2,3,4,5], tasks = [[1,100],[2,400],[3,100],[3,400]]

+ +

Output: 1000

+ +

Explanation:

+ + +
+ +

Example 2:

+ +
+

Input: workers = [10,10000,100000000], tasks = [[1,100]]

+ +

Output: 100

+ +

Explanation:

+ +

Since no worker matches the skill requirement, only the additional worker can complete task 0.

+
+ +

Example 3:

+ +
+

Input: workers = [7], tasks = [[3,3],[3,3]]

+ +

Output: 3

+ +

Explanation:

+ +

The additional worker completes task 1. Worker 0 cannot work since no task has a skill requirement of 7.

+
+ +

 

+

Constraints:

+ + + + + +## 解法 + + + +### 方法一:哈希表 + 优先队列 + +由于每个任务只能被一个特定技能的工人完成,因此,我们可以将任务按技能要求分组,放在一个哈希表 $\textit{d}$ 中,其中键是技能要求,值是一个优先队列,按照利润从大到小排序。 + +然后,我们遍历工人,对于每个工人,我们从哈希表 $\textit{d}$ 中找到其技能要求对应的优先队列,取出队首元素,即该工人能获得的最大利润,然后将其从优先队列中移除。如果优先队列为空,我们将其从哈希表中移除。 + +最后,我们将剩余任务中的最大利润加到结果中。 + +时间复杂度 $O((n + m) \times \log m)$,空间复杂度 $O(m)$。其中 $n$ 和 $m$ 分别是工人和任务的数量。 + + + +#### Python3 + +```python +class Solution: + def maxProfit(self, workers: List[int], tasks: List[List[int]]) -> int: + d = defaultdict(SortedList) + for skill, profit in tasks: + d[skill].add(profit) + ans = 0 + for skill in workers: + if not d[skill]: + continue + ans += d[skill].pop() + mx = 0 + for ls in d.values(): + if ls: + mx = max(mx, ls[-1]) + ans += mx + return ans +``` + +#### Java + +```java +class Solution { + public long maxProfit(int[] workers, int[][] tasks) { + Map> d = new HashMap<>(); + for (var t : tasks) { + int skill = t[0], profit = t[1]; + d.computeIfAbsent(skill, k -> new PriorityQueue<>((a, b) -> b - a)).offer(profit); + } + long ans = 0; + for (int skill : workers) { + if (d.containsKey(skill)) { + var pq = d.get(skill); + ans += pq.poll(); + if (pq.isEmpty()) { + d.remove(skill); + } + } + } + int mx = 0; + for (var pq : d.values()) { + mx = Math.max(mx, pq.peek()); + } + ans += mx; + return ans; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + long long maxProfit(vector& workers, vector>& tasks) { + unordered_map> d; + for (const auto& t : tasks) { + d[t[0]].push(t[1]); + } + long long ans = 0; + for (int skill : workers) { + if (d.contains(skill)) { + auto& pq = d[skill]; + ans += pq.top(); + pq.pop(); + if (pq.empty()) { + d.erase(skill); + } + } + } + int mx = 0; + for (const auto& [_, pq] : d) { + mx = max(mx, pq.top()); + } + ans += mx; + return ans; + } +}; +``` + +#### Go + +```go +func maxProfit(workers []int, tasks [][]int) (ans int64) { + d := make(map[int]*hp) + for _, t := range tasks { + skill, profit := t[0], t[1] + if _, ok := d[skill]; !ok { + d[skill] = &hp{} + } + d[skill].push(profit) + } + for _, skill := range workers { + if _, ok := d[skill]; !ok { + continue + } + ans += int64(d[skill].pop()) + if d[skill].Len() == 0 { + delete(d, skill) + } + } + mx := 0 + for _, pq := range d { + for pq.Len() > 0 { + mx = max(mx, pq.pop()) + } + } + ans += int64(mx) + return +} + +type hp struct{ sort.IntSlice } + +func (h hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] } +func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) } +func (h *hp) Pop() any { + a := h.IntSlice + v := a[len(a)-1] + h.IntSlice = a[:len(a)-1] + return v +} +func (h *hp) push(v int) { heap.Push(h, v) } +func (h *hp) pop() int { return heap.Pop(h).(int) } +``` + +#### TypeScript + +```ts +function maxProfit(workers: number[], tasks: number[][]): number { + const d = new Map(); + for (const [skill, profit] of tasks) { + if (!d.has(skill)) { + d.set(skill, new MaxPriorityQueue()); + } + d.get(skill).enqueue(profit); + } + let ans = 0; + for (const skill of workers) { + const pq = d.get(skill); + if (pq) { + ans += pq.dequeue(); + if (pq.size() === 0) { + d.delete(skill); + } + } + } + let mx = 0; + for (const pq of d.values()) { + mx = Math.max(mx, pq.front()); + } + ans += mx; + return ans; +} +``` + + + + + + diff --git a/solution/3400-3499/3476.Maximize Profit from Task Assignment/README_EN.md b/solution/3400-3499/3476.Maximize Profit from Task Assignment/README_EN.md new file mode 100644 index 0000000000000..acf45cb4d9a3e --- /dev/null +++ b/solution/3400-3499/3476.Maximize Profit from Task Assignment/README_EN.md @@ -0,0 +1,260 @@ +--- +comments: true +difficulty: Medium +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3400-3499/3476.Maximize%20Profit%20from%20Task%20Assignment/README_EN.md +--- + + + +# [3476. Maximize Profit from Task Assignment 🔒](https://leetcode.com/problems/maximize-profit-from-task-assignment) + +[中文文档](/solution/3400-3499/3476.Maximize%20Profit%20from%20Task%20Assignment/README.md) + +## Description + + + +

You are given an integer array workers, where workers[i] represents the skill level of the ith worker. You are also given a 2D integer array tasks, where:

+ +
    +
  • tasks[i][0] represents the skill requirement needed to complete the task.
  • +
  • tasks[i][1] represents the profit earned from completing the task.
  • +
+ +

Each worker can complete at most one task, and they can only take a task if their skill level is equal to the task's skill requirement. An additional worker joins today who can take up any task, regardless of the skill requirement.

+ +

Return the maximum total profit that can be earned by optimally assigning the tasks to the workers.

+ +

 

+

Example 1:

+ +
+

Input: workers = [1,2,3,4,5], tasks = [[1,100],[2,400],[3,100],[3,400]]

+ +

Output: 1000

+ +

Explanation:

+ +
    +
  • Worker 0 completes task 0.
  • +
  • Worker 1 completes task 1.
  • +
  • Worker 2 completes task 3.
  • +
  • The additional worker completes task 2.
  • +
+
+ +

Example 2:

+ +
+

Input: workers = [10,10000,100000000], tasks = [[1,100]]

+ +

Output: 100

+ +

Explanation:

+ +

Since no worker matches the skill requirement, only the additional worker can complete task 0.

+
+ +

Example 3:

+ +
+

Input: workers = [7], tasks = [[3,3],[3,3]]

+ +

Output: 3

+ +

Explanation:

+ +

The additional worker completes task 1. Worker 0 cannot work since no task has a skill requirement of 7.

+
+ +

 

+

Constraints:

+ +
    +
  • 1 <= workers.length <= 105
  • +
  • 1 <= workers[i] <= 109
  • +
  • 1 <= tasks.length <= 105
  • +
  • tasks[i].length == 2
  • +
  • 1 <= tasks[i][0], tasks[i][1] <= 109
  • +
+ + + +## Solutions + + + +### Solution 1: Hash Table + Priority Queue + +Since each task can only be completed by a worker with a specific skill, we can group the tasks by skill requirements and store them in a hash table $\textit{d}$, where the key is the skill requirement and the value is a priority queue sorted by profit in descending order. + +Then, we iterate through the workers. For each worker, we find the corresponding priority queue in the hash table $\textit{d}$ based on their skill requirement, take the front element (i.e., the maximum profit the worker can earn), and remove it from the priority queue. If the priority queue is empty, we remove it from the hash table. + +Finally, we add the maximum profit from the remaining tasks to the result. + +The time complexity is $O((n + m) \times \log m)$, and the space complexity is $O(m)$. Where $n$ and $m$ are the number of workers and tasks, respectively. + + + +#### Python3 + +```python +class Solution: + def maxProfit(self, workers: List[int], tasks: List[List[int]]) -> int: + d = defaultdict(SortedList) + for skill, profit in tasks: + d[skill].add(profit) + ans = 0 + for skill in workers: + if not d[skill]: + continue + ans += d[skill].pop() + mx = 0 + for ls in d.values(): + if ls: + mx = max(mx, ls[-1]) + ans += mx + return ans +``` + +#### Java + +```java +class Solution { + public long maxProfit(int[] workers, int[][] tasks) { + Map> d = new HashMap<>(); + for (var t : tasks) { + int skill = t[0], profit = t[1]; + d.computeIfAbsent(skill, k -> new PriorityQueue<>((a, b) -> b - a)).offer(profit); + } + long ans = 0; + for (int skill : workers) { + if (d.containsKey(skill)) { + var pq = d.get(skill); + ans += pq.poll(); + if (pq.isEmpty()) { + d.remove(skill); + } + } + } + int mx = 0; + for (var pq : d.values()) { + mx = Math.max(mx, pq.peek()); + } + ans += mx; + return ans; + } +} +``` + +#### C++ + +```cpp +class Solution { +public: + long long maxProfit(vector& workers, vector>& tasks) { + unordered_map> d; + for (const auto& t : tasks) { + d[t[0]].push(t[1]); + } + long long ans = 0; + for (int skill : workers) { + if (d.contains(skill)) { + auto& pq = d[skill]; + ans += pq.top(); + pq.pop(); + if (pq.empty()) { + d.erase(skill); + } + } + } + int mx = 0; + for (const auto& [_, pq] : d) { + mx = max(mx, pq.top()); + } + ans += mx; + return ans; + } +}; +``` + +#### Go + +```go +func maxProfit(workers []int, tasks [][]int) (ans int64) { + d := make(map[int]*hp) + for _, t := range tasks { + skill, profit := t[0], t[1] + if _, ok := d[skill]; !ok { + d[skill] = &hp{} + } + d[skill].push(profit) + } + for _, skill := range workers { + if _, ok := d[skill]; !ok { + continue + } + ans += int64(d[skill].pop()) + if d[skill].Len() == 0 { + delete(d, skill) + } + } + mx := 0 + for _, pq := range d { + for pq.Len() > 0 { + mx = max(mx, pq.pop()) + } + } + ans += int64(mx) + return +} + +type hp struct{ sort.IntSlice } + +func (h hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] } +func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) } +func (h *hp) Pop() any { + a := h.IntSlice + v := a[len(a)-1] + h.IntSlice = a[:len(a)-1] + return v +} +func (h *hp) push(v int) { heap.Push(h, v) } +func (h *hp) pop() int { return heap.Pop(h).(int) } +``` + +#### TypeScript + +```ts +function maxProfit(workers: number[], tasks: number[][]): number { + const d = new Map(); + for (const [skill, profit] of tasks) { + if (!d.has(skill)) { + d.set(skill, new MaxPriorityQueue()); + } + d.get(skill).enqueue(profit); + } + let ans = 0; + for (const skill of workers) { + const pq = d.get(skill); + if (pq) { + ans += pq.dequeue(); + if (pq.size() === 0) { + d.delete(skill); + } + } + } + let mx = 0; + for (const pq of d.values()) { + mx = Math.max(mx, pq.front()); + } + ans += mx; + return ans; +} +``` + + + + + + diff --git a/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.cpp b/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.cpp new file mode 100644 index 0000000000000..692cd0ca5fbd1 --- /dev/null +++ b/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.cpp @@ -0,0 +1,26 @@ +class Solution { +public: + long long maxProfit(vector& workers, vector>& tasks) { + unordered_map> d; + for (const auto& t : tasks) { + d[t[0]].push(t[1]); + } + long long ans = 0; + for (int skill : workers) { + if (d.contains(skill)) { + auto& pq = d[skill]; + ans += pq.top(); + pq.pop(); + if (pq.empty()) { + d.erase(skill); + } + } + } + int mx = 0; + for (const auto& [_, pq] : d) { + mx = max(mx, pq.top()); + } + ans += mx; + return ans; + } +}; diff --git a/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.go b/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.go new file mode 100644 index 0000000000000..6c6b6852563a3 --- /dev/null +++ b/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.go @@ -0,0 +1,40 @@ +func maxProfit(workers []int, tasks [][]int) (ans int64) { + d := make(map[int]*hp) + for _, t := range tasks { + skill, profit := t[0], t[1] + if _, ok := d[skill]; !ok { + d[skill] = &hp{} + } + d[skill].push(profit) + } + for _, skill := range workers { + if _, ok := d[skill]; !ok { + continue + } + ans += int64(d[skill].pop()) + if d[skill].Len() == 0 { + delete(d, skill) + } + } + mx := 0 + for _, pq := range d { + for pq.Len() > 0 { + mx = max(mx, pq.pop()) + } + } + ans += int64(mx) + return +} + +type hp struct{ sort.IntSlice } + +func (h hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] } +func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) } +func (h *hp) Pop() any { + a := h.IntSlice + v := a[len(a)-1] + h.IntSlice = a[:len(a)-1] + return v +} +func (h *hp) push(v int) { heap.Push(h, v) } +func (h *hp) pop() int { return heap.Pop(h).(int) } diff --git a/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.java b/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.java new file mode 100644 index 0000000000000..0bd7970814656 --- /dev/null +++ b/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.java @@ -0,0 +1,25 @@ +class Solution { + public long maxProfit(int[] workers, int[][] tasks) { + Map> d = new HashMap<>(); + for (var t : tasks) { + int skill = t[0], profit = t[1]; + d.computeIfAbsent(skill, k -> new PriorityQueue<>((a, b) -> b - a)).offer(profit); + } + long ans = 0; + for (int skill : workers) { + if (d.containsKey(skill)) { + var pq = d.get(skill); + ans += pq.poll(); + if (pq.isEmpty()) { + d.remove(skill); + } + } + } + int mx = 0; + for (var pq : d.values()) { + mx = Math.max(mx, pq.peek()); + } + ans += mx; + return ans; + } +} diff --git a/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.py b/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.py new file mode 100644 index 0000000000000..17ab2ad7d2cce --- /dev/null +++ b/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.py @@ -0,0 +1,16 @@ +class Solution: + def maxProfit(self, workers: List[int], tasks: List[List[int]]) -> int: + d = defaultdict(SortedList) + for skill, profit in tasks: + d[skill].add(profit) + ans = 0 + for skill in workers: + if not d[skill]: + continue + ans += d[skill].pop() + mx = 0 + for ls in d.values(): + if ls: + mx = max(mx, ls[-1]) + ans += mx + return ans diff --git a/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.ts b/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.ts new file mode 100644 index 0000000000000..d171aafcb2f92 --- /dev/null +++ b/solution/3400-3499/3476.Maximize Profit from Task Assignment/Solution.ts @@ -0,0 +1,25 @@ +function maxProfit(workers: number[], tasks: number[][]): number { + const d = new Map(); + for (const [skill, profit] of tasks) { + if (!d.has(skill)) { + d.set(skill, new MaxPriorityQueue()); + } + d.get(skill).enqueue(profit); + } + let ans = 0; + for (const skill of workers) { + const pq = d.get(skill); + if (pq) { + ans += pq.dequeue(); + if (pq.size() === 0) { + d.delete(skill); + } + } + } + let mx = 0; + for (const pq of d.values()) { + mx = Math.max(mx, pq.front()); + } + ans += mx; + return ans; +} diff --git a/solution/CONTEST_README.md b/solution/CONTEST_README.md index 3b62e2dcec0e0..3ff7a4c5f0f67 100644 --- a/solution/CONTEST_README.md +++ b/solution/CONTEST_README.md @@ -38,7 +38,7 @@ comments: true - [3467. 将数组按照奇偶性转化](/solution/3400-3499/3467.Transform%20Array%20by%20Parity/README.md) - [3468. 可行数组的数目](/solution/3400-3499/3468.Find%20the%20Number%20of%20Copy%20Arrays/README.md) - [3469. 移除所有数组元素的最小代价](/solution/3400-3499/3469.Find%20Minimum%20Cost%20to%20Remove%20Array%20Elements/README.md) -- [3470. 排列 IV](/solution/3400-3499/3470.Permutations%20IV/README.md) +- [3470. 全排列 IV](/solution/3400-3499/3470.Permutations%20IV/README.md) #### 第 438 场周赛(2025-02-23 10:30, 90 分钟) 参赛人数 2401 diff --git a/solution/DATABASE_README.md b/solution/DATABASE_README.md index 0d922eacde07a..8775cd596f6ff 100644 --- a/solution/DATABASE_README.md +++ b/solution/DATABASE_README.md @@ -311,7 +311,7 @@ | 3436 | [查找合法邮箱](/solution/3400-3499/3436.Find%20Valid%20Emails/README.md) | `数据库` | 简单 | | | 3451 | [查找无效的 IP 地址](/solution/3400-3499/3451.Find%20Invalid%20IP%20Addresses/README.md) | `数据库` | 困难 | | | 3465 | [查找具有有效序列号的产品](/solution/3400-3499/3465.Find%20Products%20with%20Valid%20Serial%20Numbers/README.md) | `数据库` | 简单 | | -| 3475 | [DNA Pattern Recognition](/solution/3400-3499/3475.DNA%20Pattern%20Recognition/README.md) | | 中等 | | +| 3475 | [DNA 模式识别](/solution/3400-3499/3475.DNA%20Pattern%20Recognition/README.md) | | 中等 | | ## 版权 diff --git a/solution/README.md b/solution/README.md index b9fa2377468e9..0a1559a7b770b 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3480,12 +3480,13 @@ | 3467 | [将数组按照奇偶性转化](/solution/3400-3499/3467.Transform%20Array%20by%20Parity/README.md) | | 简单 | 第 151 场双周赛 | | 3468 | [可行数组的数目](/solution/3400-3499/3468.Find%20the%20Number%20of%20Copy%20Arrays/README.md) | | 中等 | 第 151 场双周赛 | | 3469 | [移除所有数组元素的最小代价](/solution/3400-3499/3469.Find%20Minimum%20Cost%20to%20Remove%20Array%20Elements/README.md) | | 中等 | 第 151 场双周赛 | -| 3470 | [排列 IV](/solution/3400-3499/3470.Permutations%20IV/README.md) | | 困难 | 第 151 场双周赛 | +| 3470 | [全排列 IV](/solution/3400-3499/3470.Permutations%20IV/README.md) | | 困难 | 第 151 场双周赛 | | 3471 | [找出最大的几近缺失整数](/solution/3400-3499/3471.Find%20the%20Largest%20Almost%20Missing%20Integer/README.md) | | 简单 | 第 439 场周赛 | | 3472 | [至多 K 次操作后的最长回文子序列](/solution/3400-3499/3472.Longest%20Palindromic%20Subsequence%20After%20at%20Most%20K%20Operations/README.md) | | 中等 | 第 439 场周赛 | | 3473 | [长度至少为 M 的 K 个子数组之和](/solution/3400-3499/3473.Sum%20of%20K%20Subarrays%20With%20Length%20at%20Least%20M/README.md) | | 中等 | 第 439 场周赛 | | 3474 | [字典序最小的生成字符串](/solution/3400-3499/3474.Lexicographically%20Smallest%20Generated%20String/README.md) | | 困难 | 第 439 场周赛 | -| 3475 | [DNA Pattern Recognition](/solution/3400-3499/3475.DNA%20Pattern%20Recognition/README.md) | | 中等 | | +| 3475 | [DNA 模式识别](/solution/3400-3499/3475.DNA%20Pattern%20Recognition/README.md) | | 中等 | | +| 3476 | [Maximize Profit from Task Assignment](/solution/3400-3499/3476.Maximize%20Profit%20from%20Task%20Assignment/README.md) | | 中等 | 🔒 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index 27aa102be574d..b55b5d0be94aa 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -3484,6 +3484,7 @@ Press Control + F(or Command + F on | 3473 | [Sum of K Subarrays With Length at Least M](/solution/3400-3499/3473.Sum%20of%20K%20Subarrays%20With%20Length%20at%20Least%20M/README_EN.md) | | Medium | Weekly Contest 439 | | 3474 | [Lexicographically Smallest Generated String](/solution/3400-3499/3474.Lexicographically%20Smallest%20Generated%20String/README_EN.md) | | Hard | Weekly Contest 439 | | 3475 | [DNA Pattern Recognition](/solution/3400-3499/3475.DNA%20Pattern%20Recognition/README_EN.md) | | Medium | | +| 3476 | [Maximize Profit from Task Assignment](/solution/3400-3499/3476.Maximize%20Profit%20from%20Task%20Assignment/README_EN.md) | | Medium | 🔒 | ## Copyright