不会DP真不行啊,要开始练习DP了
给n个数,他们是严格上升序列,问他们的最大个数的子序列保持严格上升且相邻两个有公约数。
一个数组max[j]去记录 当前子串的最后一个数 含有因子j的 最长长度。另一个数组dp[x]去记录最后一个数是数x的最长长度。
那么dp[x] = Max(dp[x],Max(max[j],max[x/j])+1);
然后更新max[j] max[x/j]为dp[x] 因为dp[x]肯定是当前含有因子j x/j 的最大子序列值
最后遍历一遍dp[x]找最大。
#include<stdio.h>
#include<string.h>
using namespace std;
#define INF 10000000
int n,su[100001],dp[100001],max[100001];
int Max(int a,int b){
return a>b?a:b;
}
int main(){
while(scanf("%d",&n)!=EOF){
memset(max,0,sizeof(max));
memset(dp,0,sizeof(dp));
int x=0;
for(int i=0;i<n;i++){
scanf("%d",&x);
dp[x]=1;
for(int j=2;j*j<=x;j++){
if(x%j==0){
dp[x]=Max(dp[x],Max(max[j],max[x/j])+1);
}
}
for(int j=1;j*j<=x;j++){
if(x%j==0){
max[j]=dp[x];
max[x/j]=dp[x];
}
}
}
int ans=0;
for(int i=0;i<=x;i++){
if(ans<dp[i])
ans=dp[i];
}
printf("%d\n",ans);
}
return 0;
}