题意:
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... i∗2,i∗3,i∗4...转移,复杂度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;
}