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

题意:
n个数,要求取得最多的数,使得任意两个数其中一个为另一个倍数。

思路:
则定义 d p [ i ] dp[i] dp[i]为第i个数为取出序列数中最大数时,最多取多少数。
d p [ i ] dp[i] dp[i] i ∗ 2 , i ∗ 3 , i ∗ 4... i*2,i*3,i*4... i2,i3,i4...转移,复杂度1e7log

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;

typedef long long ll;
const int maxn = 2e5 + 7;
const int maxm = 1e7 + 7;
int a[maxn];
int vis[maxm];
int dp[maxm];

int main() {
    
    
    int n;scanf("%d",&n);
    vector<int>vec;
    int mx = 0;
    for(int i = 1;i <= n;i++) {
    
    
        int x;scanf("%d",&x);
        vec.push_back(x);
        mx = max(mx,x);
        vis[x]++;
    }
    int ans = 0;
    for(int i = 1;i <= mx;i++) {
    
    
        dp[i] = vis[i];
    }
    sort(vec.begin(),vec.end());
    vec.erase(unique(vec.begin(),vec.end()),vec.end());
    
    for(int i = 0;i < vec.size();i++) {
    
    
        ll num = vec[i];
        for(int j = 2;j <= maxm;j++) {
    
    
            num += vec[i];
            if(num > mx) break;
            if(!vis[num]) continue;
            dp[num] = max(dp[num],vis[num] + dp[vec[i]]);
        }
    }
    for(int i = 1;i <= mx;i++) {
    
    
        ans = max(ans,dp[i]);
    }
    printf("%d\n",ans);
    return 0;
}


猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/109281318