一道运用数学特征的dp题,尽管现在很忙,但是这样的题值得去做....
O(n*n)的算法是很容易被想到的,直接暴力即可,但铁定超时,这个时候就要运用数学规律来解决......仍然令d(x)为以数x位结束的最长数列的长度。f(x)是max(d[p]),其中x是p的约数。这样复杂度大概为O(n*sqrt(n))....附代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#define ss(a) scanf("%d",&a)
//#define cl(a) memset(a,0,sizeof(a))
#define N 100005
using namespace std;
int d[N],f[N],a[N];
int main()
{
int n,i,j,mmax;
ss(n);
for (i=1;i<=n;i++) ss(a[i]);
mmax=-1;
for (i=1;i<=n;i++)
{
int k=a[i];
d[k]=1;
for (j=2;j*j<=k;j++)
if (k%j==0)
{
d[k]=max(d[k],f[j]+1);
d[k]=max(d[k],f[k/j]+1);
}
for (j=2;j*j<=k;j++)
if (k%j==0)
{
f[j]=max(f[j],d[k]);
f[k/j]=max(f[k/j],d[k]);
}
f[k]=max(f[k],d[k]);
if (d[k]>mmax) mmax=d[k];
}
cout<<mmax<<endl;
return 0;
}