Skip to content

Commit 13ee900

Browse files
committed
feat: add solutions to lc problem: No.1799
No.1799.Maximize Score After N Operations
1 parent 847c11d commit 13ee900

File tree

6 files changed

+380
-2
lines changed

6 files changed

+380
-2
lines changed

solution/1700-1799/1799.Maximize Score After N Operations/README.md

+139-1
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,160 @@
6060

6161
<!-- 这里可写通用的实现逻辑 -->
6262

63+
**方法一:状态压缩 + 动态规划**
64+
65+
我们可以先预处理得到数组 `nums` 中任意两个数的最大公约数,存储在二维数组 $f$ 中,其中 $f[i][j]$ 表示 $nums[i]$ 和 $nums[j]$ 的最大公约数。
66+
67+
然后定义 $dp[k]$ 表示当前操作后的状态为 $k$ 时,可以获得的最大分数和。假设 $m$ 为数组 `nums` 中的元素个数,那么状态一共有 $2^m$ 种,即 $k$ 的取值范围为 $[0, 2^m - 1]$。
68+
69+
从小到大枚举所有状态,对于每个状态 $k$,先判断此状态中二进制位的个数 $cnt$ 是否为偶数,是则进行如下操作:
70+
71+
枚举 $k$ 中二进制位为 1 的位置,假设为 $i$ 和 $j$,则 $i$ 和 $j$ 两个位置的元素可以进行一次操作,此时可以获得的分数为 $\frac{cnt}{2} * f[i][j]$,更新 $dp[k]$ 的最大值。
72+
73+
最终答案即为 $dp[2^m - 1]$。
74+
75+
时间复杂度 $O(2^m * m^2)$,空间复杂度 $O(2^m)$。其中 $m$ 为数组 `nums` 中的元素个数。
76+
6377
<!-- tabs:start -->
6478

6579
### **Python3**
6680

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

6983
```python
70-
84+
class Solution:
85+
def maxScore(self, nums: List[int]) -> int:
86+
m = len(nums)
87+
f = [[0] * m for _ in range(m)]
88+
for i in range(m):
89+
for j in range(i + 1, m):
90+
f[i][j] = gcd(nums[i], nums[j])
91+
dp = [0] * (1 << m)
92+
for k in range(1 << m):
93+
if (cnt := k.bit_count()) % 2 == 0:
94+
for i in range(m):
95+
if k >> i & 1:
96+
for j in range(i + 1, m):
97+
if k >> j & 1:
98+
dp[k] = max(dp[k], dp[k ^ (1 << i) ^ (
99+
1 << j)] + cnt // 2 * f[i][j])
100+
return dp[-1]
71101
```
72102

73103
### **Java**
74104

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

77107
```java
108+
class Solution {
109+
public int maxScore(int[] nums) {
110+
int m = nums.length;
111+
int[][] f = new int[m][m];
112+
for (int i = 0; i < m; ++i) {
113+
for (int j = i + 1; j < m; ++j) {
114+
f[i][j] = gcd(nums[i], nums[j]);
115+
}
116+
}
117+
int[] dp = new int[1 << m];
118+
for (int k = 0; k < 1 << m; ++k) {
119+
int cnt = Integer.bitCount(k);
120+
if (cnt % 2 == 0) {
121+
for (int i = 0; i < m; ++i) {
122+
if (((k >> i) & 1) == 1) {
123+
for (int j = i + 1; j < m; ++j) {
124+
if (((k >> j) & 1) == 1) {
125+
dp[k] = Math.max(dp[k], dp[k ^ (1 << i) ^ (1 << j)] + cnt / 2 * f[i][j]);
126+
}
127+
}
128+
}
129+
}
130+
}
131+
}
132+
return dp[(1 << m) - 1];
133+
}
134+
135+
private int gcd(int a, int b) {
136+
return b == 0 ? a : gcd(b, a % b);
137+
}
138+
}
139+
```
140+
141+
### **C++**
142+
143+
```cpp
144+
class Solution {
145+
public:
146+
int maxScore(vector<int>& nums) {
147+
int m = nums.size();
148+
int f[m][m];
149+
for (int i = 0; i < m; ++i) {
150+
for (int j = i + 1; j < m; ++j) {
151+
f[i][j] = gcd(nums[i], nums[j]);
152+
}
153+
}
154+
int dp[1 << m];
155+
memset(dp, 0, sizeof dp);
156+
for (int k = 0; k < 1 << m; ++k) {
157+
int cnt = __builtin_popcount(k);
158+
if (cnt % 2 == 0) {
159+
for (int i = 0; i < m; ++i) {
160+
if (k >> i & 1) {
161+
for (int j = i + 1; j < m; ++j) {
162+
if (k >> j & 1) {
163+
dp[k] = max(dp[k], dp[k ^ (1 << i) ^ (1 << j)] + cnt / 2 * f[i][j]);
164+
}
165+
}
166+
}
167+
}
168+
}
169+
}
170+
return dp[(1 << m) - 1];
171+
}
172+
};
173+
```
78174
175+
### **Go**
176+
177+
```go
178+
func maxScore(nums []int) int {
179+
m := len(nums)
180+
f := [14][14]int{}
181+
for i := 0; i < m; i++ {
182+
for j := i + 1; j < m; j++ {
183+
f[i][j] = gcd(nums[i], nums[j])
184+
}
185+
}
186+
dp := make([]int, 1<<m)
187+
for k := 0; k < 1<<m; k++ {
188+
cnt := bits.OnesCount(uint(k))
189+
if cnt%2 == 0 {
190+
for i := 0; i < m; i++ {
191+
if k>>i&1 == 1 {
192+
for j := i + 1; j < m; j++ {
193+
if k>>j&1 == 1 {
194+
dp[k] = max(dp[k], dp[k^(1<<i)^(1<<j)]+cnt/2*f[i][j])
195+
}
196+
}
197+
}
198+
}
199+
}
200+
}
201+
return dp[1<<m-1]
202+
}
203+
204+
func max(a, b int) int {
205+
if a > b {
206+
return a
207+
}
208+
return b
209+
}
210+
211+
func gcd(a, b int) int {
212+
if b == 0 {
213+
return a
214+
}
215+
return gcd(b, a%b)
216+
}
79217
```
80218

81219
### **...**

solution/1700-1799/1799.Maximize Score After N Operations/README_EN.md

+125-1
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,137 @@
6262
### **Python3**
6363

6464
```python
65-
65+
class Solution:
66+
def maxScore(self, nums: List[int]) -> int:
67+
m = len(nums)
68+
f = [[0] * m for _ in range(m)]
69+
for i in range(m):
70+
for j in range(i + 1, m):
71+
f[i][j] = gcd(nums[i], nums[j])
72+
dp = [0] * (1 << m)
73+
for k in range(1 << m):
74+
if (cnt := k.bit_count()) % 2 == 0:
75+
for i in range(m):
76+
if k >> i & 1:
77+
for j in range(i + 1, m):
78+
if k >> j & 1:
79+
dp[k] = max(dp[k], dp[k ^ (1 << i) ^ (
80+
1 << j)] + cnt // 2 * f[i][j])
81+
return dp[-1]
6682
```
6783

6884
### **Java**
6985

7086
```java
87+
class Solution {
88+
public int maxScore(int[] nums) {
89+
int m = nums.length;
90+
int[][] f = new int[m][m];
91+
for (int i = 0; i < m; ++i) {
92+
for (int j = i + 1; j < m; ++j) {
93+
f[i][j] = gcd(nums[i], nums[j]);
94+
}
95+
}
96+
int[] dp = new int[1 << m];
97+
for (int k = 0; k < 1 << m; ++k) {
98+
int cnt = Integer.bitCount(k);
99+
if (cnt % 2 == 0) {
100+
for (int i = 0; i < m; ++i) {
101+
if (((k >> i) & 1) == 1) {
102+
for (int j = i + 1; j < m; ++j) {
103+
if (((k >> j) & 1) == 1) {
104+
dp[k] = Math.max(dp[k], dp[k ^ (1 << i) ^ (1 << j)] + cnt / 2 * f[i][j]);
105+
}
106+
}
107+
}
108+
}
109+
}
110+
}
111+
return dp[(1 << m) - 1];
112+
}
113+
114+
private int gcd(int a, int b) {
115+
return b == 0 ? a : gcd(b, a % b);
116+
}
117+
}
118+
```
119+
120+
### **C++**
121+
122+
```cpp
123+
class Solution {
124+
public:
125+
int maxScore(vector<int>& nums) {
126+
int m = nums.size();
127+
int f[m][m];
128+
for (int i = 0; i < m; ++i) {
129+
for (int j = i + 1; j < m; ++j) {
130+
f[i][j] = gcd(nums[i], nums[j]);
131+
}
132+
}
133+
int dp[1 << m];
134+
memset(dp, 0, sizeof dp);
135+
for (int k = 0; k < 1 << m; ++k) {
136+
int cnt = __builtin_popcount(k);
137+
if (cnt % 2 == 0) {
138+
for (int i = 0; i < m; ++i) {
139+
if (k >> i & 1) {
140+
for (int j = i + 1; j < m; ++j) {
141+
if (k >> j & 1) {
142+
dp[k] = max(dp[k], dp[k ^ (1 << i) ^ (1 << j)] + cnt / 2 * f[i][j]);
143+
}
144+
}
145+
}
146+
}
147+
}
148+
}
149+
return dp[(1 << m) - 1];
150+
}
151+
};
152+
```
71153
154+
### **Go**
155+
156+
```go
157+
func maxScore(nums []int) int {
158+
m := len(nums)
159+
f := [14][14]int{}
160+
for i := 0; i < m; i++ {
161+
for j := i + 1; j < m; j++ {
162+
f[i][j] = gcd(nums[i], nums[j])
163+
}
164+
}
165+
dp := make([]int, 1<<m)
166+
for k := 0; k < 1<<m; k++ {
167+
cnt := bits.OnesCount(uint(k))
168+
if cnt%2 == 0 {
169+
for i := 0; i < m; i++ {
170+
if k>>i&1 == 1 {
171+
for j := i + 1; j < m; j++ {
172+
if k>>j&1 == 1 {
173+
dp[k] = max(dp[k], dp[k^(1<<i)^(1<<j)]+cnt/2*f[i][j])
174+
}
175+
}
176+
}
177+
}
178+
}
179+
}
180+
return dp[1<<m-1]
181+
}
182+
183+
func max(a, b int) int {
184+
if a > b {
185+
return a
186+
}
187+
return b
188+
}
189+
190+
func gcd(a, b int) int {
191+
if b == 0 {
192+
return a
193+
}
194+
return gcd(b, a%b)
195+
}
72196
```
73197

74198
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution {
2+
public:
3+
int maxScore(vector<int>& nums) {
4+
int m = nums.size();
5+
int f[m][m];
6+
for (int i = 0; i < m; ++i) {
7+
for (int j = i + 1; j < m; ++j) {
8+
f[i][j] = gcd(nums[i], nums[j]);
9+
}
10+
}
11+
int dp[1 << m];
12+
memset(dp, 0, sizeof dp);
13+
for (int k = 0; k < 1 << m; ++k) {
14+
int cnt = __builtin_popcount(k);
15+
if (cnt % 2 == 0) {
16+
for (int i = 0; i < m; ++i) {
17+
if (k >> i & 1) {
18+
for (int j = i + 1; j < m; ++j) {
19+
if (k >> j & 1) {
20+
dp[k] = max(dp[k], dp[k ^ (1 << i) ^ (1 << j)] + cnt / 2 * f[i][j]);
21+
}
22+
}
23+
}
24+
}
25+
}
26+
}
27+
return dp[(1 << m) - 1];
28+
}
29+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
func maxScore(nums []int) int {
2+
m := len(nums)
3+
f := [14][14]int{}
4+
for i := 0; i < m; i++ {
5+
for j := i + 1; j < m; j++ {
6+
f[i][j] = gcd(nums[i], nums[j])
7+
}
8+
}
9+
dp := make([]int, 1<<m)
10+
for k := 0; k < 1<<m; k++ {
11+
cnt := bits.OnesCount(uint(k))
12+
if cnt%2 == 0 {
13+
for i := 0; i < m; i++ {
14+
if k>>i&1 == 1 {
15+
for j := i + 1; j < m; j++ {
16+
if k>>j&1 == 1 {
17+
dp[k] = max(dp[k], dp[k^(1<<i)^(1<<j)]+cnt/2*f[i][j])
18+
}
19+
}
20+
}
21+
}
22+
}
23+
}
24+
return dp[1<<m-1]
25+
}
26+
27+
func max(a, b int) int {
28+
if a > b {
29+
return a
30+
}
31+
return b
32+
}
33+
34+
func gcd(a, b int) int {
35+
if b == 0 {
36+
return a
37+
}
38+
return gcd(b, a%b)
39+
}

0 commit comments

Comments
 (0)