Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define LSOne(a) ((a) & -(a))
- typedef vector< int > vi;
- #define OO int(1e9)
- const int N = 15;
- int numDiffPF[15000]; // num of distinct primes
- int memo[N][1 << N];
- int n ,a[N];
- void modified_sieve(int upperbound)
- {
- for(int i = 2 ; i < upperbound ; i++)
- if( !numDiffPF[i] )
- for(int j = i ; j < upperbound ; j += i)
- numDiffPF[j] += 1;
- }
- int calc(int i ,int Mask)
- {
- if( i == n ) return !Mask ? 0 : -OO;
- int &re = memo[i][Mask];
- if( re + 1 ) return re;
- /// --- Pruning The DP A Bit --- ///
- /// --- store the valid elements only and ignour the taken ones --- ///
- /// --- and that make for loop that try all subsets faster alot --- ///
- vi b;
- int size = 0;
- int tmp = Mask;
- while( tmp )
- {
- int lsone = LSOne(tmp);
- b.push_back(lsone);
- tmp -= lsone;
- size += 1;
- }
- /// --- Try All SubSets In The New Valid Smaller Set --- ///
- re = -OO;
- for(int pick = 0 ; pick < (1 << size) ; pick += 1)
- {
- int tmpMask = pick; // Mask For Cur Taken SubSet Of Elements
- int newMask = Mask; // Get New BitMask For The Next Elements
- // get num of distinct primes factors from it
- int sum = 0;
- // Iterate Over Taken Element And Update newMask and Sum --- ///
- while( tmpMask )
- {
- int lsone = LSOne(tmpMask);
- tmpMask -= lsone;
- int j = __builtin_ctz(lsone);
- sum += a[ __builtin_ctz(b[j]) ];
- // Turn Of bits that was valid and now taken
- newMask ^= b[j];
- }
- // Update DP
- re = max(re ,calc(i + 1 ,newMask) + numDiffPF[sum]);
- }
- return re;
- }
- int main()
- {
- modified_sieve(15000);
- scanf("%d" ,&n);
- for(int i = 0 ; i < n ; i++)
- scanf("%d" ,&a[i]);
- memset(memo ,-1 ,sizeof memo);
- printf("%d" ,calc(0 ,(1 << n) - 1));
- }
Add Comment
Please, Sign In to add comment