Skip to content

Commit 680aeef

Browse files
authored
feat: add solutions to lc problem: No.3946 (#5239)
1 parent 0bba58e commit 680aeef

7 files changed

Lines changed: 412 additions & 8 deletions

File tree

solution/3900-3999/3946.Maximum Number of Items From Sale I/README.md

Lines changed: 141 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,32 +81,169 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3900-3999/3946.Ma
8181

8282
<!-- solution:start -->
8383

84-
### 方法一
84+
### 方法一:动态规划(0-1 背包)
85+
86+
由于第一个购买一种物品是特殊的,购买后可以获得免费物品,因此,我们把第一次购买的物品和后续购买的物品分开考虑。
87+
88+
对于第一次购买的物品,假设我们消耗了 $i$ 的预算,可以获得 $f[i]$ 个物品(包括购买的物品和免费获得的物品)。对于后续购买的物品,我们可以用剩余的预算 $\text{budget} - i$ 来购买价格最低的物品,获得 $\lfloor \frac{\text{budget} - i}{\text{mn}} \rfloor$ 个物品,其中 $\text{mn}$ 是所有物品中价格最低的物品的价格。因此,我们可以枚举第一次购买的物品消耗的预算 $i$,计算出 $f[i] + \lfloor \frac{\text{budget} - i}{\text{mn}} \rfloor$ 的最大值,即为最终答案。
89+
90+
时间复杂度 $O(n^2 + n \times m)$,其中 $n$ 是物品的数量,而 $m$ 是预算的大小。
8591

8692
<!-- tabs:start -->
8793

8894
#### Python3
8995

9096
```python
91-
97+
class Solution:
98+
def maximumSaleItems(self, items: List[List[int]], budget: int) -> int:
99+
f = [0] * (budget + 1)
100+
mn = inf
101+
for factor, price in items:
102+
mn = min(mn, price)
103+
cnt = sum(factor_j % factor == 0 for factor_j, _ in items)
104+
for j in range(budget, price - 1, -1):
105+
f[j] = max(f[j], f[j - price] + cnt)
106+
return max(x + (budget - i) // mn for i, x in enumerate(f))
92107
```
93108

94109
#### Java
95110

96111
```java
97-
112+
class Solution {
113+
public int maximumSaleItems(int[][] items, int budget) {
114+
int[] f = new int[budget + 1];
115+
int mn = Integer.MAX_VALUE;
116+
117+
for (int[] item : items) {
118+
int factor = item[0];
119+
int price = item[1];
120+
121+
mn = Math.min(mn, price);
122+
123+
int cnt = 0;
124+
for (int[] jItem : items) {
125+
if (jItem[0] % factor == 0) {
126+
cnt++;
127+
}
128+
}
129+
130+
for (int j = budget; j >= price; j--) {
131+
f[j] = Math.max(f[j], f[j - price] + cnt);
132+
}
133+
}
134+
135+
int ans = 0;
136+
for (int i = 0; i <= budget; i++) {
137+
ans = Math.max(ans, f[i] + (budget - i) / mn);
138+
}
139+
140+
return ans;
141+
}
142+
}
98143
```
99144

100145
#### C++
101146

102147
```cpp
103-
148+
class Solution {
149+
public:
150+
int maximumSaleItems(vector<vector<int>>& items, int budget) {
151+
vector<int> f(budget + 1, 0);
152+
int mn = INT_MAX;
153+
154+
for (const auto& item : items) {
155+
int factor = item[0];
156+
int price = item[1];
157+
158+
mn = min(mn, price);
159+
160+
int cnt = 0;
161+
for (const auto& jItem : items) {
162+
if (jItem[0] % factor == 0) {
163+
cnt++;
164+
}
165+
}
166+
167+
for (int j = budget; j >= price; --j) {
168+
f[j] = max(f[j], f[j - price] + cnt);
169+
}
170+
}
171+
172+
int ans = 0;
173+
for (int i = 0; i <= budget; ++i) {
174+
ans = max(ans, f[i] + (budget - i) / mn);
175+
}
176+
177+
return ans;
178+
}
179+
};
104180
```
105181

106182
#### Go
107183

108184
```go
185+
func maximumSaleItems(items [][]int, budget int) int {
186+
f := make([]int, budget+1)
187+
mn := math.MaxInt32
188+
189+
for _, item := range items {
190+
factor := item[0]
191+
price := item[1]
192+
mn = min(mn, price)
193+
194+
cnt := 0
195+
for _, jItem := range items {
196+
if jItem[0]%factor == 0 {
197+
cnt++
198+
}
199+
}
200+
201+
for j := budget; j >= price; j-- {
202+
if f[j-price]+cnt > f[j] {
203+
f[j] = f[j-price] + cnt
204+
}
205+
}
206+
}
207+
208+
ans := 0
209+
for i, x := range f {
210+
extra := (budget - i) / mn
211+
ans = max(ans, x+extra)
212+
}
213+
214+
return ans
215+
}
216+
```
217+
218+
#### TypeScript
219+
220+
```ts
221+
function maximumSaleItems(items: number[][], budget: number): number {
222+
const f: number[] = new Array(budget + 1).fill(0);
223+
let mn: number = Infinity;
224+
225+
for (const [factor, price] of items) {
226+
mn = Math.min(mn, price);
227+
228+
let cnt = 0;
229+
for (const [factor_j, _] of items) {
230+
if (factor_j % factor === 0) {
231+
cnt++;
232+
}
233+
}
234+
235+
for (let j = budget; j >= price; j--) {
236+
f[j] = Math.max(f[j], f[j - price] + cnt);
237+
}
238+
}
239+
240+
let ans = 0;
241+
for (let i = 0; i <= budget; i++) {
242+
ans = Math.max(ans, f[i] + Math.floor((budget - i) / mn));
243+
}
109244

245+
return ans;
246+
}
110247
```
111248

112249
<!-- tabs:end -->

solution/3900-3999/3946.Maximum Number of Items From Sale I/README_EN.md

Lines changed: 141 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,32 +79,169 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3900-3999/3946.Ma
7979

8080
<!-- solution:start -->
8181

82-
### Solution 1
82+
### Solution 1: Dynamic Programming (0-1 Knapsack)
83+
84+
Since buying the first item of a type is special and yields free items, we consider the first purchased item separately from the later purchases.
85+
86+
For the first purchased item, suppose we spend a budget of $i$ and obtain $f[i]$ items in total, including both the purchased item and the free items. For the later purchases, we can use the remaining budget $\text{budget} - i$ to buy the cheapest item, obtaining $\lfloor \frac{\text{budget} - i}{\text{mn}} \rfloor$ items, where $\text{mn}$ is the minimum price among all items. Therefore, we enumerate the budget $i$ spent on the first purchase and compute the maximum value of $f[i] + \lfloor \frac{\text{budget} - i}{\text{mn}} \rfloor$, which is the final answer.
87+
88+
The time complexity is $O(n^2 + n \times m)$, where $n$ is the number of items and $m$ is the budget.
8389

8490
<!-- tabs:start -->
8591

8692
#### Python3
8793

8894
```python
89-
95+
class Solution:
96+
def maximumSaleItems(self, items: List[List[int]], budget: int) -> int:
97+
f = [0] * (budget + 1)
98+
mn = inf
99+
for factor, price in items:
100+
mn = min(mn, price)
101+
cnt = sum(factor_j % factor == 0 for factor_j, _ in items)
102+
for j in range(budget, price - 1, -1):
103+
f[j] = max(f[j], f[j - price] + cnt)
104+
return max(x + (budget - i) // mn for i, x in enumerate(f))
90105
```
91106

92107
#### Java
93108

94109
```java
95-
110+
class Solution {
111+
public int maximumSaleItems(int[][] items, int budget) {
112+
int[] f = new int[budget + 1];
113+
int mn = Integer.MAX_VALUE;
114+
115+
for (int[] item : items) {
116+
int factor = item[0];
117+
int price = item[1];
118+
119+
mn = Math.min(mn, price);
120+
121+
int cnt = 0;
122+
for (int[] jItem : items) {
123+
if (jItem[0] % factor == 0) {
124+
cnt++;
125+
}
126+
}
127+
128+
for (int j = budget; j >= price; j--) {
129+
f[j] = Math.max(f[j], f[j - price] + cnt);
130+
}
131+
}
132+
133+
int ans = 0;
134+
for (int i = 0; i <= budget; i++) {
135+
ans = Math.max(ans, f[i] + (budget - i) / mn);
136+
}
137+
138+
return ans;
139+
}
140+
}
96141
```
97142

98143
#### C++
99144

100145
```cpp
101-
146+
class Solution {
147+
public:
148+
int maximumSaleItems(vector<vector<int>>& items, int budget) {
149+
vector<int> f(budget + 1, 0);
150+
int mn = INT_MAX;
151+
152+
for (const auto& item : items) {
153+
int factor = item[0];
154+
int price = item[1];
155+
156+
mn = min(mn, price);
157+
158+
int cnt = 0;
159+
for (const auto& jItem : items) {
160+
if (jItem[0] % factor == 0) {
161+
cnt++;
162+
}
163+
}
164+
165+
for (int j = budget; j >= price; --j) {
166+
f[j] = max(f[j], f[j - price] + cnt);
167+
}
168+
}
169+
170+
int ans = 0;
171+
for (int i = 0; i <= budget; ++i) {
172+
ans = max(ans, f[i] + (budget - i) / mn);
173+
}
174+
175+
return ans;
176+
}
177+
};
102178
```
103179

104180
#### Go
105181

106182
```go
183+
func maximumSaleItems(items [][]int, budget int) int {
184+
f := make([]int, budget+1)
185+
mn := math.MaxInt32
186+
187+
for _, item := range items {
188+
factor := item[0]
189+
price := item[1]
190+
mn = min(mn, price)
191+
192+
cnt := 0
193+
for _, jItem := range items {
194+
if jItem[0]%factor == 0 {
195+
cnt++
196+
}
197+
}
198+
199+
for j := budget; j >= price; j-- {
200+
if f[j-price]+cnt > f[j] {
201+
f[j] = f[j-price] + cnt
202+
}
203+
}
204+
}
205+
206+
ans := 0
207+
for i, x := range f {
208+
extra := (budget - i) / mn
209+
ans = max(ans, x+extra)
210+
}
211+
212+
return ans
213+
}
214+
```
215+
216+
#### TypeScript
217+
218+
```ts
219+
function maximumSaleItems(items: number[][], budget: number): number {
220+
const f: number[] = new Array(budget + 1).fill(0);
221+
let mn: number = Infinity;
222+
223+
for (const [factor, price] of items) {
224+
mn = Math.min(mn, price);
225+
226+
let cnt = 0;
227+
for (const [factor_j, _] of items) {
228+
if (factor_j % factor === 0) {
229+
cnt++;
230+
}
231+
}
232+
233+
for (let j = budget; j >= price; j--) {
234+
f[j] = Math.max(f[j], f[j - price] + cnt);
235+
}
236+
}
237+
238+
let ans = 0;
239+
for (let i = 0; i <= budget; i++) {
240+
ans = Math.max(ans, f[i] + Math.floor((budget - i) / mn));
241+
}
107242

243+
return ans;
244+
}
108245
```
109246

110247
<!-- tabs:end -->
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class Solution {
2+
public:
3+
int maximumSaleItems(vector<vector<int>>& items, int budget) {
4+
vector<int> f(budget + 1, 0);
5+
int mn = INT_MAX;
6+
7+
for (const auto& item : items) {
8+
int factor = item[0];
9+
int price = item[1];
10+
11+
mn = min(mn, price);
12+
13+
int cnt = 0;
14+
for (const auto& jItem : items) {
15+
if (jItem[0] % factor == 0) {
16+
cnt++;
17+
}
18+
}
19+
20+
for (int j = budget; j >= price; --j) {
21+
f[j] = max(f[j], f[j - price] + cnt);
22+
}
23+
}
24+
25+
int ans = 0;
26+
for (int i = 0; i <= budget; ++i) {
27+
ans = max(ans, f[i] + (budget - i) / mn);
28+
}
29+
30+
return ans;
31+
}
32+
};

0 commit comments

Comments
 (0)