首先对于这种最长子序列问题,我们首先想到动态规划。我们看一下题目的限制条件,要求序列相邻元素之间互质。互质即两个数之间的最大公约数为1,求解最大公约数在Python里面有gcd的包可以直接用,c++没有,不过可以利用牛顿的辗转相除法来写一个gcd函数,有关原理的帖子很多,这里不再赘述。ac代码如下。
#include <iostream>
using namespace std;
int max(int a,int b)
{
return a>b?a:b;
}
int gcd(int a, int b)
{
if (b==0)
{
return a;
}
return gcd(b, a % b);
}
int main()
{
int n;
cin>>n;
int a[n];
int dp[n]={1};
int ans=1;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
for(int i=0;i<n;i++)
{
for(int j=i-1;j>=0;j--)
{
if(gcd(a[i],a[j])==1)
dp[i]=max(dp[j]+1,dp[i]);
ans=max(ans,dp[i]);//因为dp[n]不一定是最长相邻互质子序列的尾数
}
}
cout<<ans<<endl;
return 0;
}
个人思考
对于动态规划问题
首先,我们需要定义一个状态数组 dp
,其中 dp[i]
表示以 a[i]
结尾的最长互质子序列的长度。
初始时,所有 dp[i]
都设为1,因为每个元素本身都可以构成一个长度为1的互质子序列。
接下来,我们需要遍历序列 a
中的每个元素,并对于每个元素 a[i]
,再遍历它之前的所有元素 a[j]
(其中 j < i
),检查 a[i]
和 a[j]
是否互质。
如果互质,那么我们可以尝试更新 dp[i]
,使其等于 dp[j] + 1
(即以 a[j]
结尾的最长互质子序列长度加1),并且我们还要确保这个新长度大于当前的 dp[i]
。
最后,我们遍历整个 dp
数组,找到其中的最大值,这个值就是满足条件的最长互质子序列的长度。