Codeforces Round #697 (Div. 3) G. Strange Beauty (DP,数学)

  • 题意:给你一组数,问你最少删去多少数,使得剩下的数,每个数都能整除数组中其它某个数或被数组中其它某个数整除.
  • 题解:我们直接枚举所有因子,(dp[i])表示(i)在数组中所含的最大因子数(当我们枚举到(i)时),然后用(dp[i])更新以(i)作为因子的更大的数,注意,更新的时候(dp[j]=max(dp[i],dp[j])),而不是(dp[j]+=dp[i]),因为这样会把之前的因子重复计算.
  • 代码:
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
#define rep(a,b,c) for(int a=b;a<=c;++a)
#define per(a,b,c) for(int a=b;a>=c;--a)
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}

int _;

int main() {
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

	cin>>_;
	while(_--){
		int n;
		cin>>n;
		vector<int> a(n);

		for(auto &w:a) cin>>w;

		int mx=*max_element(a.begin(),a.end());

		vector<int> cnt(mx+1);

		for(auto w:a){
			cnt[w]++;
		}

		vector<int> dp(mx+1,0);

		rep(i,1,mx){
			dp[i]+=cnt[i];
			for(int j=i+i;j<=mx;j+=i){
				dp[j]=max(dp[i],dp[j]);
			}
		}

		cout<<n-*max_element(dp.begin(),dp.end())<<'
';

	}
	
    return 0;
}
原文地址:https://www.cnblogs.com/lr599909928/p/14342753.html