CF #div.1 B.good sequences

来源:互联网 发布:红蚂蚁网络与阿里巴巴 编辑:程序博客网 时间:2024/06/05 08:17

不会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 10000000int 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;}


0 0