icpc小米 A . Intelligent Warehouse

[题目]https://ac.nowcoder.com/acm/contest/7501/A
题意:选出最多数量的数,这组数两两是倍数关系。
解法:1、很容易想到用dp[i]去更新i的倍数,但是会TLE,可以稍作优化,只需更新i的素数倍。比如4,如果只更新素数倍暂时就不会更新到4,而是通过22的方式去更新,减少了多余的更新次数

#include<bits/stdc++.h>
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
using namespace std ;
typedef long long ll ;
const int N = 10000009 , M = 2e5+9 ;
bool vis[N];
vector<int>pr;
int n ;
int dp[N] ;
int cnt[N];
void init(int x){
    for(int i = 2 ; i <= x ; i++){
        if(vis[i] == 0){
            pr.push_back(i);
            for(ll j = 1ll * i * i ; j <= x ; j += i){
                vis[j] = 1 ;
            }
        }
    }
}
  
void solve(){
    init(10000000);
    scanf("%d" , &n);
    for(int i = 1 , x; i <= n ; i++){
        scanf("%d" , &x);
        cnt[x]++;
    }
    int ans = 0 ;
    for(int i = 1 ; i <= 10000000 ; i++){
        int t = i;
        dp[t] = max(dp[t] , cnt[t]);
        for(auto p : pr){
            if(1ll * t * p > 10000000) break ;
            dp[t*p] = max(dp[t*p] , dp[t] + cnt[t*p]);
        }
    }
    for(int i = 1 ; i <= 10000000 ; i++){
        ans = max(ans , dp[i]);
    }
    printf("%d
" , ans);
}
  
signed main(){
    #ifdef ONLINE_JUDGE
    #else
        freopen("D:\c++\in.txt", "r", stdin);
        //freopen("D:\c++\out.txt", "w", stdout);
    #endif
        solve();
      
}
原文地址:https://www.cnblogs.com/nonames/p/13875056.html