简体   繁体   中英

Algorithm. How to find longest subsequence of integers in an array such that gcd of any two consecutive number in the sequence is greather than 1?

Given`en an array of integers. We have to find the length of the longest subsequence of integers such that gcd of any two consecutive elements in the sequence is greater than 1.

for ex: if array = [12, 8, 2, 3, 6, 9]

then one such subsequence can be = {12, 8, 2, 6, 9} other one can be= {12, 3, 6, 9}

I tried to solve this problem by dynamic programming. Assume that maxCount is the array such that maxCount[i] will have the length of such longest subsequence ending at index i.

`maxCount[0]=1 ;

for(i=1; i<N; i++)
{

   max = 1 ;

   for(j=i-1; j>=0; j--)
   {   

      if(gcd(arr[i], arr[j]) > 1)
      {
      temp = maxCount[j] + 1 ;

      if(temp > max)
       max = temp ;
     }
    }

maxCount[i]=max;

}``

max = 0;

for(i=0; i<N; i++)
{
 if(maxCount[i] > max)
   max = maxCount[i] ;
}

cout<<max<<endl ;

`

But, this approach is getting timeout. As its time complexity is O(N^2). Can we improve the time complexity?

The condition "gcd is greater than 1" means that numbers have at least one common divisor. So, let dp[i] equals to the length of longest sequence finishing on a number divisible by i .

int n;
cin >> n;

const int MAX_NUM = 100 * 1000;
static int dp[MAX_NUM];

for(int i = 0; i < n; ++i)
{
    int x;
    cin >> x;

    int cur = 1;
    vector<int> d;
    for(int i = 2; i * i <= x; ++i)
    {
        if(x % i == 0)
        {
            cur = max(cur, dp[i] + 1);
            cur = max(cur, dp[x / i] + 1);
            d.push_back(i);
            d.push_back(x / i);
        }
    }
    if(x > 1)
    {
        cur = max(cur, dp[x] + 1);
        d.push_back(x);
    }

    for(int j : d)
    {
        dp[j] = cur;
    }
}

cout << *max_element(dp, dp + MAX_NUM) << endl;

This solution has O(N * sqrt(MAX_NUM)) complexity. Actually you can calculate dp values only for prime numbers. To implement this you should be able to get prime factorization in less than O(N^0.5) time ( this method , for example). That optimization should cast complexity to O(N * factorization + Nlog(N)) . As memory optimization, you can replace dp array with map or unordered_map .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM