返回顶部

2020ICPC·小米 网络选拔赛第一场 A.Intelligent Warehouse (DP)

  • 题意:给你一组数,选一些数出来组成一个排列,使得每个数都能被前一个数整除,求排列的最大元素.

  • 题解:我们先用欧拉筛筛出\(1e7\)的质数,设\(dp[i]\)表示当前选的数都是\(i\)的约数且合法的最大元素值.所以我们可以用\(dp[i]\)去更新\(i\)的倍数的\(dp\)值,我们可以靠枚举\(i\)的素数倍来降低复杂度,因为合数总是可以由若干的素数的乘积得来.

  • 代码:

    int n;
    int x;
    int mp[N];
    int primes[N],cnt;
    bool st[N];
    int dp[N];
    
    void init(){
        for(int i=2;i<=1e7;++i){
            if(!st[i]) primes[cnt++]=i;
            for(int j=0;j<cnt && i*primes[j]<=1e7;++j){
                st[i*primes[j]]=true;
                if(i%primes[j]==0) break;
            }
        }
    }
    
    int main() {
        //ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        init();
        n=read();
    
        for(int i=1;i<=n;++i){x=read();mp[x]++;}
    
        int ans=0;
        for(int i=1;i<=1e7;++i){
            dp[i]+=mp[i];
            for(int j=0;j<cnt && i*primes[j]<=1e7;++j){
                dp[i*primes[j]]=max(dp[i*primes[j]],dp[i]);
            }
            ans=max(ans,dp[i]);
        }
    
        printf("%d\n",ans);
    
        return 0;
    }
    
posted @ 2020-10-26 20:56  _Kolibri  阅读(215)  评论(0)    收藏  举报