1
+ int dp[16384 ];
2
+ int gcd_table[14 ][14 ];
3
+
1
4
class Solution {
2
5
public:
3
6
int maxScore (vector<int >& nums) {
4
-
5
- int n = nums.size ();
6
-
7
- vector<int > dp ( 1 << n , 0 ); // dp contains score of masks - by default, scores are 0
8
-
9
- for (int i = 0 ; i < n ; i++) {// we have precomputed score for mask with only 2 set bits
10
- for (int j = 0 ; j < i ; j++){
11
- int mask = (1 << i) + (1 << j);
12
- dp[mask] = __gcd (nums[i] , nums[j]);// score after selecting only 2 nums is just their gcd
13
- }
7
+ memset (dp, -1 , sizeof (dp));
8
+ int sz = nums.size ();
9
+
10
+ // Build the GCD table
11
+ for (int i = 0 ; i < sz; ++i) {
12
+ for (int j = i+1 ; j < sz; ++j) {gcd_table[i][j] = gcd (nums[i], nums[j]);}
14
13
}
15
-
16
- dp[0 ] = 0 ; // score after selecting 0 nums is 0 by default
17
-
18
- for (int mask = 2 ; mask < (1 << n) ; mask ++ ){
19
-
20
- vector<int > nz;// here we would count and store non-zero bit positions of the mask in vector nz
21
- for (int i = 0 ; i < n ; i++)
22
- if (mask & (1 << i))
23
- nz.push_back (i);
24
-
25
- if (nz.size () % 2 ) // if set bits is odd, we cannot compute as we need pairs for gcd
26
- continue ;
27
-
28
- if (nz.size () == 2 )// since we have precomputed dp for mask with only 2 set bits above
29
- continue ;
30
-
31
- int op = nz.size () / 2 ; // we are performing opth operation now
32
-
33
- for (int i = 0 ; i < nz.size () ; i++) // nz[i]th bit not in submask
34
- {
35
- for (int j = 0 ; j < i ; j++){ // nz[j]th bit not in submask
36
-
37
- int pos1 = nz[i];
38
- int pos2 = nz[j];
39
- int submask = (mask ^ (1 << pos1)) ^ (1 << pos2);
40
-
41
- int g = dp[(1 << pos1) + (1 << pos2)] ;// to be added to get dp[mask] from dp[submask]
42
-
43
- dp[mask] = max (dp[mask] , op * g + dp[submask]);
44
- // maximizing dp[mask] using the recursive equation explained above
14
+
15
+ // Looping from state 0 to (1<<sz)-1
16
+ dp[0 ] = 0 ;
17
+ for (int s = 0 ; s < (1 <<sz); ++s) {
18
+ int cnt = __builtin_popcount (s);
19
+ if (cnt &1 )continue ; // bitcount can't be odd
20
+ for (int i = 0 ; i < sz; ++i) {
21
+ if (s & (1 <<i)) continue ;
22
+ for (int j = i+1 ; j < sz; ++j) {
23
+ if (s & (1 <<j)) continue ;
24
+ int next_state = s^(1 <<i)^(1 <<j);
25
+ dp[next_state] = max (dp[next_state], dp[s] + (cnt/2 +1 )*gcd_table[i][j]);
45
26
}
46
27
}
47
-
48
28
}
49
-
50
- return dp.back ();
51
-
29
+ return dp[(1 <<sz)-1 ];
52
30
}
53
- };
31
+ };
0 commit comments