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\n" , ans);
}
signed main(){
#ifdef ONLINE_JUDGE
#else
freopen("D:\\c++\\in.txt", "r", stdin);
//freopen("D:\\c++\\out.txt", "w", stdout);
#endif
solve();
}