Advertisement
Guest User

TREE

a guest
Jun 20th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.17 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int inf = 1e9 + 7;
  5. int t, n;
  6. long long a[10], npd[10], dp[10][1<<10];
  7.  
  8. void megumi() {
  9.     scanf("%d", &n); long long ans = inf;
  10.     for(int i = 0; i < n; i++) {
  11.         for(int j = 0; j < (1<<n); j++) dp[i][j] = inf;
  12.     }
  13.     for(int i = 0; i < n; i++) scanf("%lld", &a[i]);
  14.     sort(a, a + n);
  15.     for(int i = 0; i < n; i++) {
  16.         long long k = a[i], p = sqrt(k); bool isPrime = true; npd[i] = 0;
  17.         for(int j = 2; j <= p; j++) {
  18.             if(k % j == 0) {
  19.                 isPrime = false;
  20.                 while(k % j == 0) k /= j, npd[i]++;
  21.             }
  22.         }
  23.         if(k > 1) npd[i]++;
  24.         if(not isPrime) npd[i]++;
  25.         //cout << i << " " << npd[i] << "\n";
  26.     }
  27.     dp[0][1<<(n-1)] = npd[0];
  28.     for(int i = 1; i < n; i++) {
  29.         for(int prev = 1; prev < (1<<(i+1)); prev++) {
  30.             for(int cur = 1; cur < (1<<(i+1)); cur++) {
  31.                 int m1 = (prev<<(n-i-1)), m2 = (cur<<(n-i-1)), tot = npd[i];
  32.                 //cout << "mask " << m1 << " " << m2 << "\n";
  33.                 long long res = a[i]; bool pos = true, numofSubtree = false;
  34.                 if(not (cur&1)) continue;
  35.                 for(int l = i; l > 0; l--) {
  36.                     //cout << l << " " << ((prev>>l)&1) << " " << ((cur>>l)&1) << "\n";
  37.                     if((not ((prev>>l)&1)) && ((cur>>l)&1)) {
  38.                         pos = false;
  39.                         break;
  40.                     }
  41.                     else if(((prev>>l)&1) && not ((cur>>l)&1)) {
  42.                         //cout << a[i-l] << " has been multiplied to the root\n";
  43.                         if(res % a[i-l] != 0) {
  44.                             pos = false;
  45.                             break; 
  46.                         }
  47.                         else res /= a[i-l], tot -= npd[i-l] - (npd[i-l] > 1);
  48.                     }
  49.                     else if(((prev>>l)&1) && ((cur>>l)&1)) numofSubtree = 1;
  50.                 }
  51.                 if(not pos) continue;
  52.                 long long current_res = dp[i-1][m1] + tot, initnumofSubtree = __builtin_popcount(prev);
  53.                 if(initnumofSubtree > 1 && not numofSubtree) current_res--;
  54.                 else if(initnumofSubtree == 1 && numofSubtree) current_res++;
  55.                 dp[i][m2] = min(dp[i][m2], current_res);
  56.             }
  57.         }
  58.         //cout << "consider to " << i << "th number\n";
  59.         //for(int j = 1; j < (1<<(i+1)); j++) cout << (j<<(n-i-1)) << " " << dp[i][(j<<(n-i-1))] << "\n";  
  60.     }
  61.     for(int j = 1; j < (1<<n); j++) ans = min(ans, dp[n-1][j]);
  62.     printf("%lld\n", ans);
  63. }
  64.  
  65. int main() {
  66.     freopen("test.txt", "r", stdin);
  67.     scanf("%d", &t);
  68.     while(t--) megumi();
  69. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement