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; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮