Skip to content

Commit 0232939

Browse files
committed
feat: add solutions to lc problem: No.0879
No.0879.Profitable Schemes
1 parent b9302bc commit 0232939

File tree

7 files changed

+308
-3
lines changed

7 files changed

+308
-3
lines changed

solution/0800-0899/0879.Profitable Schemes/README.md

+112-1
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,133 @@
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56+
**方法一:动态规划**
57+
58+
我们定义 $f[i][j][k]$ 表示前 $i$ 个工作中,选择了 $j$ 个员工,且至少产生 $k$ 的利润的方案数。初始时 $f[0][j][0] = 1$,表示不选择任何工作,且至少产生 $0$ 的利润的方案数为 $1$。答案即为 $f[m][n][minProfit]$。
59+
60+
对于第 $i$ 个工作,我们可以选择参与或不参与。如果不参与,则 $f[i][j][k] = f[i - 1][j][k]$;如果参与,则 $f[i][j][k] = f[i - 1][j - group[i - 1]][max(0, k - profit[i - 1])]$。我们需要枚举 $j$ 和 $k$,并将所有的方案数相加。
61+
62+
最终的答案即为 $f[m][n][minProfit]$。
63+
64+
时间复杂度 $O(m \times n \times minProfit)$,空间复杂度 $O(m \times n \times minProfit)$。其中 $m$ 和 $n$ 分别为工作的数量和员工的数量,而 $minProfit$ 为至少产生的利润。
65+
5666
<!-- tabs:start -->
5767

5868
### **Python3**
5969

6070
<!-- 这里可写当前语言的特殊实现逻辑 -->
6171

6272
```python
63-
73+
class Solution:
74+
def profitableSchemes(self, n: int, minProfit: int, group: List[int], profit: List[int]) -> int:
75+
mod = 10**9 + 7
76+
m = len(group)
77+
f = [[[0] * (minProfit + 1) for _ in range(n + 1)]
78+
for _ in range(m + 1)]
79+
for j in range(n + 1):
80+
f[0][j][0] = 1
81+
for i, (x, p) in enumerate(zip(group, profit), 1):
82+
for j in range(n + 1):
83+
for k in range(minProfit + 1):
84+
f[i][j][k] = f[i - 1][j][k]
85+
if j >= x:
86+
f[i][j][k] = (f[i][j][k] + f[i - 1]
87+
[j - x][max(0, k - p)]) % mod
88+
return f[m][n][minProfit]
6489
```
6590

6691
### **Java**
6792

6893
<!-- 这里可写当前语言的特殊实现逻辑 -->
6994

7095
```java
96+
class Solution {
97+
public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) {
98+
final int mod = (int) 1e9 + 7;
99+
int m = group.length;
100+
int[][][] f = new int[m + 1][n + 1][minProfit + 1];
101+
for (int j = 0; j <= n; ++j) {
102+
f[0][j][0] = 1;
103+
}
104+
for (int i = 1; i <= m; ++i) {
105+
for (int j = 0; j <= n; ++j) {
106+
for (int k = 0; k <= minProfit; ++k) {
107+
f[i][j][k] = f[i - 1][j][k];
108+
if (j >= group[i - 1]) {
109+
f[i][j][k] = (f[i][j][k] + f[i - 1][j - group[i - 1]][Math.max(0, k - profit[i - 1])]) % mod;
110+
}
111+
}
112+
}
113+
}
114+
return f[m][n][minProfit];
115+
}
116+
}
117+
```
118+
119+
### **C++**
120+
121+
```cpp
122+
class Solution {
123+
public:
124+
int profitableSchemes(int n, int minProfit, vector<int>& group, vector<int>& profit) {
125+
int m = group.size();
126+
int f[m + 1][n + 1][minProfit + 1];
127+
memset(f, 0, sizeof(f));
128+
for (int j = 0; j <= n; ++j) {
129+
f[0][j][0] = 1;
130+
}
131+
const int mod = 1e9 + 7;
132+
for (int i = 1; i <= m; ++i) {
133+
for (int j = 0; j <= n; ++j) {
134+
for (int k = 0; k <= minProfit; ++k) {
135+
f[i][j][k] = f[i - 1][j][k];
136+
if (j >= group[i - 1]) {
137+
f[i][j][k] = (f[i][j][k] + f[i - 1][j - group[i - 1]][max(0, k - profit[i - 1])]) % mod;
138+
}
139+
}
140+
}
141+
}
142+
return f[m][n][minProfit];
143+
}
144+
};
145+
```
71146
147+
### **Go**
148+
149+
```go
150+
func profitableSchemes(n int, minProfit int, group []int, profit []int) int {
151+
m := len(group)
152+
f := make([][][]int, m+1)
153+
for i := range f {
154+
f[i] = make([][]int, n+1)
155+
for j := range f[i] {
156+
f[i][j] = make([]int, minProfit+1)
157+
}
158+
}
159+
for j := 0; j <= n; j++ {
160+
f[0][j][0] = 1
161+
}
162+
const mod = 1e9 + 7
163+
for i := 1; i <= m; i++ {
164+
for j := 0; j <= n; j++ {
165+
for k := 0; k <= minProfit; k++ {
166+
f[i][j][k] = f[i-1][j][k]
167+
if j >= group[i-1] {
168+
f[i][j][k] += f[i-1][j-group[i-1]][max(0, k-profit[i-1])]
169+
f[i][j][k] %= mod
170+
}
171+
}
172+
}
173+
}
174+
return f[m][n][minProfit]
175+
}
176+
177+
func max(a, b int) int {
178+
if a > b {
179+
return a
180+
}
181+
return b
182+
}
72183
```
73184

74185
### **...**

solution/0800-0899/0879.Profitable Schemes/README_EN.md

+102-1
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,114 @@ There are 7 possible schemes: (0), (1), (2), (0,1), (0,2), (1,2), and (0,1,2).</
4646
### **Python3**
4747

4848
```python
49-
49+
class Solution:
50+
def profitableSchemes(self, n: int, minProfit: int, group: List[int], profit: List[int]) -> int:
51+
mod = 10**9 + 7
52+
m = len(group)
53+
f = [[[0] * (minProfit + 1) for _ in range(n + 1)]
54+
for _ in range(m + 1)]
55+
for j in range(n + 1):
56+
f[0][j][0] = 1
57+
for i, (x, p) in enumerate(zip(group, profit), 1):
58+
for j in range(n + 1):
59+
for k in range(minProfit + 1):
60+
f[i][j][k] = f[i - 1][j][k]
61+
if j >= x:
62+
f[i][j][k] = (f[i][j][k] + f[i - 1]
63+
[j - x][max(0, k - p)]) % mod
64+
return f[m][n][minProfit]
5065
```
5166

5267
### **Java**
5368

5469
```java
70+
class Solution {
71+
public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) {
72+
final int mod = (int) 1e9 + 7;
73+
int m = group.length;
74+
int[][][] f = new int[m + 1][n + 1][minProfit + 1];
75+
for (int j = 0; j <= n; ++j) {
76+
f[0][j][0] = 1;
77+
}
78+
for (int i = 1; i <= m; ++i) {
79+
for (int j = 0; j <= n; ++j) {
80+
for (int k = 0; k <= minProfit; ++k) {
81+
f[i][j][k] = f[i - 1][j][k];
82+
if (j >= group[i - 1]) {
83+
f[i][j][k] = (f[i][j][k] + f[i - 1][j - group[i - 1]][Math.max(0, k - profit[i - 1])]) % mod;
84+
}
85+
}
86+
}
87+
}
88+
return f[m][n][minProfit];
89+
}
90+
}
91+
```
92+
93+
### **C++**
94+
95+
```cpp
96+
class Solution {
97+
public:
98+
int profitableSchemes(int n, int minProfit, vector<int>& group, vector<int>& profit) {
99+
int m = group.size();
100+
int f[m + 1][n + 1][minProfit + 1];
101+
memset(f, 0, sizeof(f));
102+
for (int j = 0; j <= n; ++j) {
103+
f[0][j][0] = 1;
104+
}
105+
const int mod = 1e9 + 7;
106+
for (int i = 1; i <= m; ++i) {
107+
for (int j = 0; j <= n; ++j) {
108+
for (int k = 0; k <= minProfit; ++k) {
109+
f[i][j][k] = f[i - 1][j][k];
110+
if (j >= group[i - 1]) {
111+
f[i][j][k] = (f[i][j][k] + f[i - 1][j - group[i - 1]][max(0, k - profit[i - 1])]) % mod;
112+
}
113+
}
114+
}
115+
}
116+
return f[m][n][minProfit];
117+
}
118+
};
119+
```
55120
121+
### **Go**
122+
123+
```go
124+
func profitableSchemes(n int, minProfit int, group []int, profit []int) int {
125+
m := len(group)
126+
f := make([][][]int, m+1)
127+
for i := range f {
128+
f[i] = make([][]int, n+1)
129+
for j := range f[i] {
130+
f[i][j] = make([]int, minProfit+1)
131+
}
132+
}
133+
for j := 0; j <= n; j++ {
134+
f[0][j][0] = 1
135+
}
136+
const mod = 1e9 + 7
137+
for i := 1; i <= m; i++ {
138+
for j := 0; j <= n; j++ {
139+
for k := 0; k <= minProfit; k++ {
140+
f[i][j][k] = f[i-1][j][k]
141+
if j >= group[i-1] {
142+
f[i][j][k] += f[i-1][j-group[i-1]][max(0, k-profit[i-1])]
143+
f[i][j][k] %= mod
144+
}
145+
}
146+
}
147+
}
148+
return f[m][n][minProfit]
149+
}
150+
151+
func max(a, b int) int {
152+
if a > b {
153+
return a
154+
}
155+
return b
156+
}
56157
```
57158

58159
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Solution {
2+
public:
3+
int profitableSchemes(int n, int minProfit, vector<int>& group, vector<int>& profit) {
4+
int m = group.size();
5+
int f[m + 1][n + 1][minProfit + 1];
6+
memset(f, 0, sizeof(f));
7+
for (int j = 0; j <= n; ++j) {
8+
f[0][j][0] = 1;
9+
}
10+
const int mod = 1e9 + 7;
11+
for (int i = 1; i <= m; ++i) {
12+
for (int j = 0; j <= n; ++j) {
13+
for (int k = 0; k <= minProfit; ++k) {
14+
f[i][j][k] = f[i - 1][j][k];
15+
if (j >= group[i - 1]) {
16+
f[i][j][k] = (f[i][j][k] + f[i - 1][j - group[i - 1]][max(0, k - profit[i - 1])]) % mod;
17+
}
18+
}
19+
}
20+
}
21+
return f[m][n][minProfit];
22+
}
23+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
func profitableSchemes(n int, minProfit int, group []int, profit []int) int {
2+
m := len(group)
3+
f := make([][][]int, m+1)
4+
for i := range f {
5+
f[i] = make([][]int, n+1)
6+
for j := range f[i] {
7+
f[i][j] = make([]int, minProfit+1)
8+
}
9+
}
10+
for j := 0; j <= n; j++ {
11+
f[0][j][0] = 1
12+
}
13+
const mod = 1e9 + 7
14+
for i := 1; i <= m; i++ {
15+
for j := 0; j <= n; j++ {
16+
for k := 0; k <= minProfit; k++ {
17+
f[i][j][k] = f[i-1][j][k]
18+
if j >= group[i-1] {
19+
f[i][j][k] += f[i-1][j-group[i-1]][max(0, k-profit[i-1])]
20+
f[i][j][k] %= mod
21+
}
22+
}
23+
}
24+
}
25+
return f[m][n][minProfit]
26+
}
27+
28+
func max(a, b int) int {
29+
if a > b {
30+
return a
31+
}
32+
return b
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution {
2+
public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) {
3+
final int mod = (int) 1e9 + 7;
4+
int m = group.length;
5+
int[][][] f = new int[m + 1][n + 1][minProfit + 1];
6+
for (int j = 0; j <= n; ++j) {
7+
f[0][j][0] = 1;
8+
}
9+
for (int i = 1; i <= m; ++i) {
10+
for (int j = 0; j <= n; ++j) {
11+
for (int k = 0; k <= minProfit; ++k) {
12+
f[i][j][k] = f[i - 1][j][k];
13+
if (j >= group[i - 1]) {
14+
f[i][j][k] = (f[i][j][k] + f[i - 1][j - group[i - 1]][Math.max(0, k - profit[i - 1])]) % mod;
15+
}
16+
}
17+
}
18+
}
19+
return f[m][n][minProfit];
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Solution:
2+
def profitableSchemes(self, n: int, minProfit: int, group: List[int], profit: List[int]) -> int:
3+
mod = 10**9 + 7
4+
m = len(group)
5+
f = [[[0] * (minProfit + 1) for _ in range(n + 1)]
6+
for _ in range(m + 1)]
7+
for j in range(n + 1):
8+
f[0][j][0] = 1
9+
for i, (x, p) in enumerate(zip(group, profit), 1):
10+
for j in range(n + 1):
11+
for k in range(minProfit + 1):
12+
f[i][j][k] = f[i - 1][j][k]
13+
if j >= x:
14+
f[i][j][k] = (f[i][j][k] + f[i - 1]
15+
[j - x][max(0, k - p)]) % mod
16+
return f[m][n][minProfit]

solution/1000-1099/1012.Numbers With Repeated Digits/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
1. 将数字 $n$ 转为整型数组 $nums$,其中 $nums[0]$ 为最低位,而 $nums[i]$ 为最高位;
5959
1. 根据题目信息,设计函数 $dfs()$,对于本题,我们定义 $dfs(pos, mask, lead, limit)$,其中:
6060

61-
- 参数 $pos$ 表示当前搜索到的数字的位数,从末位或者第一位开始,一般根据题目的数字构造性质来选择顺序。对于本题,我们选择从高位开始,因此$pos$ 的初始值为数字的高位下标;
61+
- 参数 $pos$ 表示当前搜索到的数字的位数,从末位或者第一位开始,一般根据题目的数字构造性质来选择顺序。对于本题,我们选择从高位开始,因此 $pos$ 的初始值为数字的高位下标;
6262
- 参数 $mask$ 表示当前数字中出现过的数字;
6363
- 参数 $lead$ 表示当前数字是否仅包含前导零;
6464
- 参数 $limit$ 表示当前可填的数字的限制,如果无限制,那么可以选择 $i \in [0,1,..9]$,否则,只能选择 $i \in [0,..nums[pos]]$。如果 $limit$ 为 `true` 且已经取到了能取到的最大值,那么下一个 $limit$ 同样为 `true`;如果 $limit$ 为 `true` 但是还没有取到最大值,或者 $limit$ 为 `false`,那么下一个 $limit$ 为 `false`

0 commit comments

Comments
 (0)