给定一个长度为\(n\)的序列,要求移除最少的元素元素使得对于任意\(i,j\),\(a_i\)是\(a_j\)的倍数或者\(a_j\)是\(a_i\)的倍数
其实就是数论吧 很容易想到正解应该是\(O(nlogn)\)的,怎么做呢?令\(dp[i]\)表示最大的数字为\(i\)的最大符合要求的集合大小,那么\(dp[i] = cnt[i] + max\{dp[j]\},i \equiv 0(mod j)\)
最后找到\(dp[i]\)的最大值,减一减就好了
int dp[maxn];
int cnt[maxn];
void solve(){
int n = rd();
for(int i = 0;i < maxn;i++)
dp[i] = cnt[i] = 0;
for(int i = 0;i < n;i++)
cnt[rd()]++;
for(int i = 1;i < maxn;i++){
dp[i] += cnt[i];
for(int j = i + i;j < maxn;j += i)
dp[j] = max(dp[j],dp[i]);
}
cout << (n - *max_element(dp,dp + maxn)) << ‘\n‘;
}
int main(){
int T = rd();
while(T--)
solve();
}
CodeForces -1475G Strange Beauty 数论 动态规划
原文:https://www.cnblogs.com/hznumqf/p/14379876.html