简体   繁体   English

算法。 如何找到数组中最长的整数子序列,以使序列中任意两个连续数字的gcd大于1?

[英]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. 我们必须找到整数的最长子序列的长度,以使序列中任何两个连续元素的gcd都大于1。

for ex: if array = [12, 8, 2, 3, 6, 9] 例如:如果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} 那么一个这样的子序列可以是= {12,8,2,6,9}其他一个可以是= {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是一个数组,这样maxCount [i]的最长子序列的长度将以索引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). 由于其时间复杂度为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. 条件“ gcd大于1”表示数字具有至少一个公共除数。 So, let dp[i] equals to the length of longest sequence finishing on a number divisible by i . 因此,令dp[i]等于在被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. 此解决方案具有O(N * sqrt(MAX_NUM))复杂度。 Actually you can calculate dp values only for prime numbers. 实际上,您只能计算素数的dp值。 To implement this you should be able to get prime factorization in less than O(N^0.5) time ( this method , for example). 为了实现这一点,您应该能够在不到O(N^0.5)时间内获得素因数分解(例如, 此方法 )。 That optimization should cast complexity to O(N * factorization + Nlog(N)) . 该优化应该将复杂度转换为O(N * factorization + Nlog(N)) As memory optimization, you can replace dp array with map or unordered_map . 作为内存优化,可以将dp数组替换为mapunordered_map

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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