n2DP就不写了。
直接考虑优化:
既然相邻的两个要求不互质,那么存在同样的约数。
那么我们考虑枚举当前数x的约数,
当前情况下的最优解 只能从前面的 含x的约数的 数中的最优解转移过来。
如当前x=8,那么f[x]可以由前面的含有2或4这个约数的数中的最优解转移。
那么我们发现,可以把每个约数的最大值记录下来,转移时直接取出来就好了。
时间复杂度O(n√n)。
#include<bits/stdc++.h> #define RG register #define IL inline #define DB double #define LL long long using namespace std; IL int gi() { RG int x=0,w=0; char ch=0; while (ch<'0'||ch>'9') {if (ch=='-') w=1;ch=getchar();} while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return w?-x:x; } const int N=1e5+10; int n,ans,a[N],f[N]; int main () { //freopen ("good.in","r",stdin); //freopen ("good.out","w",stdout); RG int i,j,k,x; for (i=1,n=gi();i<=n;++i) { for (j=2,f[i]=1,k=x=gi();j*j<=x;++j) if (x%j==0) { if (f[a[j]]+1>f[i]) f[i]=f[a[j]]+1; while (x%j==0) x/=j; } if (x>1&&f[a[x]]+1>f[i]) f[i]=f[a[x]]+1; for (j=2;j*j<=k;++j) if (k%j==0) { a[j]=i; while (k%j==0) k/=j; } if (x>1) a[x]=i; ans=max(ans,f[i]); } printf("%d ",ans); return 0; }