1+ int dp[16384 ];
2+ int gcd_table[14 ][14 ];
3+
14class Solution {
25public:
36 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]);}
1413 }
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]);
4526 }
4627 }
47-
4828 }
49-
50- return dp.back ();
51-
29+ return dp[(1 <<sz)-1 ];
5230 }
53- };
31+ };
0 commit comments