2020ICPC·Xiaomi Network Trials, the first A Intelligent Warehouse (dp)

Link: https://ac.nowcoder.com/acm/contest/7501/A
Source: Niuke.com
 

Time limit: C/C++ 1 second, other languages ​​2 seconds
Space limit: C/C++ 262144K, other languages ​​524288K
64bit IO Format: %lld

Title description

In MI Intelligent Warehouse, there are nn_{}n​ products, where the ii_{}i​-th product is of size aia_iai​. We always need to box producsts into all kinds of containers, and it will be safer and more cost efficient if for any two sizes of products, one is the other's multiple, since there won't be any residual room in one container. So for each boxing we need to choose some products that for any two chosen products, either aia_iai​ is multiple of aja_jaj​ or aja_jaj​ is multiple of aia_iai​. Print the maximum number of products that can be chosen in one boxing.

Enter description:

 

The first line contains one integer n (1≤n≤2×105)

 

The second line contains n integers a1,a2,⋯ ,an (1≤ai≤107)

Output description:

Only one line containing one integer, denoting the maximum number of products we can choose in one boxing.

Example 1

enter

6
1 4 2 8 5 7

Output

4

Description

One possible choice is {1, 4, 2, 8}.

Meaning of the question: For a sequence of numbers, ask how many numbers can be selected at most, and any two numbers have a multiple relationship between them

Idea: Each number is transferred by its factor. One way is to update its multiple with each number. The complexity is O (nlogn), it may be TLE; in fact, it is only necessary to enumerate the prime multiple of i, because Composite numbers can be represented by the product of several prime numbers, and the complexityO (nloglogn)

(Positive solution is the second method, but the first one can also pass)

Compare:

Correct answer:

Violent enumeration multiple:

Today's flag: Handwriting max from now on, no need to write fast anymore

------------------------------------------------------------------------------------------------------------------

Correct answer:

#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 1e7 + 7;
int pri[N], tot;
bool vis[N];

inline int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-')
            f = -1;
        ch = getchar();
    }
    while(isdigit(ch)) {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}

void init() {
    for(int i = 0; i < N; ++i) vis[i] = 0;
    vis[0] = vis[1] = 1;
    tot = 0;
    for(int i = 2; i < N; ++i) {
        if(!vis[i]) {
            pri[++tot] = i;
            for(int j = i + i; j < N; j += i)
                vis[j] = 1;
        }
    }
}

int dp[N], a, n, cnt[N];

int main() {
    init();
    n = read();
    int maxx = 0;
    for(int i = 1; i <= n; ++i) {
        a = read();
        if(maxx < a) maxx = a;
        cnt[a]++;
    }
    int ans = 0;
    for(int i = 1; i <= maxx; ++i) {
        dp[i] += cnt[i];
        for(int j = 1; j <= tot && pri[j] * i <= maxx; ++j)
            if(dp[pri[j] * i] < dp[i]) dp[pri[j] * i] = dp[i];
        if(ans < dp[i]) ans = dp[i];
    }
    printf("%d\n", ans);
    return 0;
}

The first type: (violence

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 1e7 + 10;

inline int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-')
            f = -1;
        ch = getchar();
    }
    while(isdigit(ch)) {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}

int a[N], st[N], dp[N];
int cnt[N];

int main() {
    int n, a, tot = 0, maxx = 0;
    n = read();
    for(int i = 1; i <= n; ++i) {
        a = read();
        if(maxx < a) maxx = a;
        if(!cnt[a]) st[++tot] = a;
        cnt[a]++;
    }
    sort(st + 1, st + tot + 1);
    int ans = 0;
    for(int i = 1; i <= tot; ++i) {
        dp[st[i]] += cnt[st[i]];
        for(int j = st[i] + st[i]; j <= maxx; j += st[i]) {    ///这样写比j = 2; st[i] * j <= maxx快,because少算了好多乘法
            if(!cnt[j]) continue;
            if(dp[j] < dp[st[i]]) dp[j] = dp[st[i]];
        }
        if(ans < dp[st[i]]) ans = dp[st[i]];
    }
    printf("%d\n", ans);
	return 0;
}

 

Guess you like

Origin blog.csdn.net/weixin_43871207/article/details/109289292