Skip to content

Commit b54b83f

Browse files
authoredAug 7, 2023
feat: add solutions to lc problem: No.2172 (#1414)
No.2172.Maximum AND Sum of Array
1 parent ed7e94a commit b54b83f

File tree

7 files changed

+347
-4
lines changed

7 files changed

+347
-4
lines changed
 

‎solution/2100-2199/2172.Maximum AND Sum of Array/README.md

+132-2
Original file line numberDiff line numberDiff line change
@@ -50,28 +50,158 @@
5050

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

53+
**方法一:状态压缩 + 动态规划**
54+
55+
由于每个篮子最多只能放两个数,我们不妨将篮子数乘以 $2$,这样每个篮子最多只能放一个数。
56+
57+
接下来,我们定义 $f[i]$ 表示篮子状态为 $i$ 时的最大与和,其中 $i$ 是一个二进制数,表示每个篮子是否放了数。初始时 $f[0]=0$。
58+
59+
接下来,我们考虑 $f[i]$ 如何进行状态转移。
60+
61+
我们可以枚举 $i$,记 $i$ 的二进制表示中 $1$ 的个数为 $cnt$。如果 $cnt \gt n$,那么 $i$ 不是一个合法的状态,我们可以直接跳过。否则,我们可以枚举 $i$ 的二进制表示中的每一位 $j$,如果 $i$ 的第 $j$ 位为 $1$,那么我们可以将第 $(cnt-1)$ 个数 $nums[cnt-1]$ 放入第 $j$ 个篮子中,此时有:
62+
63+
$$
64+
f[i] = \max\{f[i], f[i \oplus (1 << j)] + (nums[cnt-1] \wedge (j / 2 + 1))\}
65+
$$
66+
67+
其中 $\oplus$ 表示异或运算,而 $\wedge$ 表示按位与运算。
68+
69+
答案为 $\max\{f[i]\}$。
70+
71+
时间复杂度 $O(4^k \times k \times 2)$,空间复杂度 $O(4^k)$。其中 $k$ 表示篮子的数量,即题目中的 $numSlots$。
72+
5373
<!-- tabs:start -->
5474

5575
### **Python3**
5676

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

5979
```python
60-
80+
class Solution:
81+
def maximumANDSum(self, nums: List[int], numSlots: int) -> int:
82+
n = len(nums)
83+
m = numSlots << 1
84+
f = [0] * (1 << m)
85+
for i in range(1 << m):
86+
cnt = i.bit_count()
87+
if cnt > n:
88+
continue
89+
for j in range(m):
90+
if i >> j & 1:
91+
f[i] = max(f[i], f[i ^ (1 << j)] + (nums[cnt - 1] & (j // 2 + 1)))
92+
return max(f)
6193
```
6294

6395
### **Java**
6496

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

6799
```java
100+
class Solution {
101+
public int maximumANDSum(int[] nums, int numSlots) {
102+
int n = nums.length;
103+
int m = numSlots << 1;
104+
int[] f = new int[1 << m];
105+
int ans = 0;
106+
for (int i = 0; i < 1 << m; ++i) {
107+
int cnt = Integer.bitCount(i);
108+
if (cnt > n) {
109+
continue;
110+
}
111+
for (int j = 0; j < m; ++j) {
112+
if ((i >> j & 1) == 1) {
113+
f[i] = Math.max(f[i], f[i ^ (1 << j)] + (nums[cnt - 1] & (j / 2 + 1)));
114+
}
115+
}
116+
ans = Math.max(ans, f[i]);
117+
}
118+
return ans;
119+
}
120+
}
121+
```
68122

123+
### **C++**
124+
125+
```cpp
126+
class Solution {
127+
public:
128+
int maximumANDSum(vector<int>& nums, int numSlots) {
129+
int n = nums.size();
130+
int m = numSlots << 1;
131+
int f[1 << m];
132+
memset(f, 0, sizeof(f));
133+
for (int i = 0; i < 1 << m; ++i) {
134+
int cnt = __builtin_popcount(i);
135+
if (cnt > n) {
136+
continue;
137+
}
138+
for (int j = 0; j < m; ++j) {
139+
if (i >> j & 1) {
140+
f[i] = max(f[i], f[i ^ (1 << j)] + (nums[cnt - 1] & (j / 2 + 1)));
141+
}
142+
}
143+
}
144+
return *max_element(f, f + (1 << m));
145+
}
146+
};
147+
```
148+
149+
### **Go**
150+
151+
```go
152+
func maximumANDSum(nums []int, numSlots int) (ans int) {
153+
n := len(nums)
154+
m := numSlots << 1
155+
f := make([]int, 1<<m)
156+
for i := range f {
157+
cnt := bits.OnesCount(uint(i))
158+
if cnt > n {
159+
continue
160+
}
161+
for j := 0; j < m; j++ {
162+
if i>>j&1 == 1 {
163+
f[i] = max(f[i], f[i^(1<<j)]+(nums[cnt-1]&(j/2+1)))
164+
}
165+
}
166+
ans = max(ans, f[i])
167+
}
168+
return
169+
}
170+
171+
func max(a, b int) int {
172+
if a > b {
173+
return a
174+
}
175+
return b
176+
}
69177
```
70178

71179
### **TypeScript**
72180

73181
```ts
74-
182+
function maximumANDSum(nums: number[], numSlots: number): number {
183+
const n = nums.length;
184+
const m = numSlots << 1;
185+
const f: number[] = new Array(1 << m).fill(0);
186+
for (let i = 0; i < 1 << m; ++i) {
187+
const cnt = i
188+
.toString(2)
189+
.split('')
190+
.filter(c => c === '1').length;
191+
if (cnt > n) {
192+
continue;
193+
}
194+
for (let j = 0; j < m; ++j) {
195+
if (((i >> j) & 1) === 1) {
196+
f[i] = Math.max(
197+
f[i],
198+
f[i ^ (1 << j)] + (nums[cnt - 1] & ((j >> 1) + 1)),
199+
);
200+
}
201+
}
202+
}
203+
return Math.max(...f);
204+
}
75205
```
76206

77207
### **...**

‎solution/2100-2199/2172.Maximum AND Sum of Array/README_EN.md

+112-2
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,129 @@ Note that slots 2, 5, 6, and 8 are empty which is permitted.
5151
### **Python3**
5252

5353
```python
54-
54+
class Solution:
55+
def maximumANDSum(self, nums: List[int], numSlots: int) -> int:
56+
n = len(nums)
57+
m = numSlots << 1
58+
f = [0] * (1 << m)
59+
for i in range(1 << m):
60+
cnt = i.bit_count()
61+
if cnt > n:
62+
continue
63+
for j in range(m):
64+
if i >> j & 1:
65+
f[i] = max(f[i], f[i ^ (1 << j)] + (nums[cnt - 1] & (j // 2 + 1)))
66+
return max(f)
5567
```
5668

5769
### **Java**
5870

5971
```java
72+
class Solution {
73+
public int maximumANDSum(int[] nums, int numSlots) {
74+
int n = nums.length;
75+
int m = numSlots << 1;
76+
int[] f = new int[1 << m];
77+
int ans = 0;
78+
for (int i = 0; i < 1 << m; ++i) {
79+
int cnt = Integer.bitCount(i);
80+
if (cnt > n) {
81+
continue;
82+
}
83+
for (int j = 0; j < m; ++j) {
84+
if ((i >> j & 1) == 1) {
85+
f[i] = Math.max(f[i], f[i ^ (1 << j)] + (nums[cnt - 1] & (j / 2 + 1)));
86+
}
87+
}
88+
ans = Math.max(ans, f[i]);
89+
}
90+
return ans;
91+
}
92+
}
93+
```
6094

95+
### **C++**
96+
97+
```cpp
98+
class Solution {
99+
public:
100+
int maximumANDSum(vector<int>& nums, int numSlots) {
101+
int n = nums.size();
102+
int m = numSlots << 1;
103+
int f[1 << m];
104+
memset(f, 0, sizeof(f));
105+
for (int i = 0; i < 1 << m; ++i) {
106+
int cnt = __builtin_popcount(i);
107+
if (cnt > n) {
108+
continue;
109+
}
110+
for (int j = 0; j < m; ++j) {
111+
if (i >> j & 1) {
112+
f[i] = max(f[i], f[i ^ (1 << j)] + (nums[cnt - 1] & (j / 2 + 1)));
113+
}
114+
}
115+
}
116+
return *max_element(f, f + (1 << m));
117+
}
118+
};
119+
```
120+
121+
### **Go**
122+
123+
```go
124+
func maximumANDSum(nums []int, numSlots int) (ans int) {
125+
n := len(nums)
126+
m := numSlots << 1
127+
f := make([]int, 1<<m)
128+
for i := range f {
129+
cnt := bits.OnesCount(uint(i))
130+
if cnt > n {
131+
continue
132+
}
133+
for j := 0; j < m; j++ {
134+
if i>>j&1 == 1 {
135+
f[i] = max(f[i], f[i^(1<<j)]+(nums[cnt-1]&(j/2+1)))
136+
}
137+
}
138+
ans = max(ans, f[i])
139+
}
140+
return
141+
}
142+
143+
func max(a, b int) int {
144+
if a > b {
145+
return a
146+
}
147+
return b
148+
}
61149
```
62150

63151
### **TypeScript**
64152

65153
```ts
66-
154+
function maximumANDSum(nums: number[], numSlots: number): number {
155+
const n = nums.length;
156+
const m = numSlots << 1;
157+
const f: number[] = new Array(1 << m).fill(0);
158+
for (let i = 0; i < 1 << m; ++i) {
159+
const cnt = i
160+
.toString(2)
161+
.split('')
162+
.filter(c => c === '1').length;
163+
if (cnt > n) {
164+
continue;
165+
}
166+
for (let j = 0; j < m; ++j) {
167+
if (((i >> j) & 1) === 1) {
168+
f[i] = Math.max(
169+
f[i],
170+
f[i ^ (1 << j)] + (nums[cnt - 1] & ((j >> 1) + 1)),
171+
);
172+
}
173+
}
174+
}
175+
return Math.max(...f);
176+
}
67177
```
68178

69179
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution {
2+
public:
3+
int maximumANDSum(vector<int>& nums, int numSlots) {
4+
int n = nums.size();
5+
int m = numSlots << 1;
6+
int f[1 << m];
7+
memset(f, 0, sizeof(f));
8+
for (int i = 0; i < 1 << m; ++i) {
9+
int cnt = __builtin_popcount(i);
10+
if (cnt > n) {
11+
continue;
12+
}
13+
for (int j = 0; j < m; ++j) {
14+
if (i >> j & 1) {
15+
f[i] = max(f[i], f[i ^ (1 << j)] + (nums[cnt - 1] & (j / 2 + 1)));
16+
}
17+
}
18+
}
19+
return *max_element(f, f + (1 << m));
20+
}
21+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
func maximumANDSum(nums []int, numSlots int) (ans int) {
2+
n := len(nums)
3+
m := numSlots << 1
4+
f := make([]int, 1<<m)
5+
for i := range f {
6+
cnt := bits.OnesCount(uint(i))
7+
if cnt > n {
8+
continue
9+
}
10+
for j := 0; j < m; j++ {
11+
if i>>j&1 == 1 {
12+
f[i] = max(f[i], f[i^(1<<j)]+(nums[cnt-1]&(j/2+1)))
13+
}
14+
}
15+
ans = max(ans, f[i])
16+
}
17+
return
18+
}
19+
20+
func max(a, b int) int {
21+
if a > b {
22+
return a
23+
}
24+
return b
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution {
2+
public int maximumANDSum(int[] nums, int numSlots) {
3+
int n = nums.length;
4+
int m = numSlots << 1;
5+
int[] f = new int[1 << m];
6+
int ans = 0;
7+
for (int i = 0; i < 1 << m; ++i) {
8+
int cnt = Integer.bitCount(i);
9+
if (cnt > n) {
10+
continue;
11+
}
12+
for (int j = 0; j < m; ++j) {
13+
if ((i >> j & 1) == 1) {
14+
f[i] = Math.max(f[i], f[i ^ (1 << j)] + (nums[cnt - 1] & (j / 2 + 1)));
15+
}
16+
}
17+
ans = Math.max(ans, f[i]);
18+
}
19+
return ans;
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class Solution:
2+
def maximumANDSum(self, nums: List[int], numSlots: int) -> int:
3+
n = len(nums)
4+
m = numSlots << 1
5+
f = [0] * (1 << m)
6+
for i in range(1 << m):
7+
cnt = i.bit_count()
8+
if cnt > n:
9+
continue
10+
for j in range(m):
11+
if i >> j & 1:
12+
f[i] = max(f[i], f[i ^ (1 << j)] + (nums[cnt - 1] & (j // 2 + 1)))
13+
return max(f)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
function maximumANDSum(nums: number[], numSlots: number): number {
2+
const n = nums.length;
3+
const m = numSlots << 1;
4+
const f: number[] = new Array(1 << m).fill(0);
5+
for (let i = 0; i < 1 << m; ++i) {
6+
const cnt = i
7+
.toString(2)
8+
.split('')
9+
.filter(c => c === '1').length;
10+
if (cnt > n) {
11+
continue;
12+
}
13+
for (let j = 0; j < m; ++j) {
14+
if (((i >> j) & 1) === 1) {
15+
f[i] = Math.max(
16+
f[i],
17+
f[i ^ (1 << j)] + (nums[cnt - 1] & ((j >> 1) + 1)),
18+
);
19+
}
20+
}
21+
}
22+
return Math.max(...f);
23+
}

0 commit comments

Comments
 (0)
Please sign in to comment.