题意
给你n个数(2e5) a[](2e5) 问你最少删掉几个使得剩下的数两两之间一个数是另一个数的因子
思路
dp[i]表示数组中留下最大值到i有多少个数能留下 ans = n - max(dp[]);
要使两两之间一个数是另一个数的因子 则如果当前最大到i,那么每个i的倍数j(i是j的因子)都能继承更新dp[i]的值,因为如果一个数k是i的因子(包含在dp[i]里) && j是i的倍数,那么k也一定是j的因子 //dp[j]=max(dp[i],dp[j]);
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MaxN = 2e5 + 5;
const int inf = 0x3f3f3f3f;
typedef long long LL;
int n,t,a,cnt[MaxN],dp[MaxN];
int main()
{
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(cnt,0,sizeof cnt);
memset(dp,0,sizeof dp);
for(int i = 1;i <= n; i++){
scanf("%d",&a);
cnt[a]++;
}
for(int i = 1;i <= 2e5; i++){
dp[i] += cnt[i];
for(int j = i + i; j <= 2e5; j += i){
dp[j] = max(dp[j],dp[i]);
}
}
int ans = 0;
for(int i = 1;i < MaxN; i++){
ans = max(ans,dp[i]);
}
printf("%d\n",n - ans);
}
return 0;
}