• CF264B Good Sequences


    Solution

    虽然每个题要求的最长序列的满足条件不一样,但是方法总是那一个——DP。

    因为前后转移和 (gcd) 有关系,我们可以将 (gcd) 用因子的方式表示。

    我们设 (dp_i) 表示以 (a_i) 结尾的最长序列, (f_i) 为所有含有 (i) 这个因子的 (a_x) 中的 (max{dp_x}) 。当方程转移到 (x) 位时,枚举 (a_x) 的因子,更新 (dp_x=maxlimits_{d|a_x,d ot=1}{f_d}+1) ,然后再将 (f_d) 更新,最后搞一个 (ans) 记录最大值就行了。

    小细节:在更新 (f_d) 的时候,可以只更新质因子的 (f) ,因为在转移的时候,用非质因子更新答案,其实在枚举质因子的时候就已经更新过了,并且质因子的答案不会比非质因子差。而且 (dp) 数组也不需要,当枚举到某一位时,这一位以前的最大值已经求出,所以可以直接和 (ans) 更新。

    代码

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    const int N=100010;
    int ans,n,a[N],f[N];
    
    inline int read(){
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
        return x*f;
    }
    
    inline void solve(int x){
        int m=sqrt(x),sum=0;
        for(int i=2;i<=m;i++)
            if(x%i==0) sum=max(max(sum,f[i]),f[x/i]);
        sum=max(sum,f[x]);//记得x也算x的因数
        for(int i=2;i<=m;i++)
            if(x%i==0){
                f[i]=sum+1;
                while(x%i==0) x/=i;
            }
        f[x]=sum+1;
        ans=max(ans,sum+1);//不记录dp[] 直接更新
    }
    
    int main(){
        n=read();
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<=n;i++) solve(a[i]);
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    算法 在连续线性空间里查找
    OSI网络模型和网络连接设备
    CPU 架构SMP/NUMA,调优
    cluster集群基本概念
    protocol buffers 使用方法
    Qt在window下的环境变量PATH的配置
    mysql connector c++ 1.1 API初步体验
    mysql connector c++ 1.1 安装
    python知识点总结01(不定时更新)
    ant-design表单自定义验证
  • 原文地址:https://www.cnblogs.com/jasony/p/13817506.html
Copyright © 2020-2023  润新知