F:Topforces Strikes Back
题意:
给定N个数,从其中最多选三个数,这三个数不能互为其它数的因子,比如选三个数:X不能是Y、Z的因子,Z不能是X、Y的因子,Y不能是X、Z的因子,求选出数的和的最大值
分析:
明显选出的数不能两两相同,先对原数组去重,那么剩下的数两两互异;考虑从小到大枚举选出的最小数,如果还能选其他的数,那么最优策略必定会选能选的数中最大的数,证明如下:如果不选最大的数(假设为X),那么在能选的数中必定存在两个X的因子使得他两的和比选X更大,但这两个数最大只可能是X/2,X/3,而X/2+X/3 < X,所以选X最优;选出X后,再选另一个数即可。去重后数组是递增的,假设选定了最小的V,那么我们最多判段 N/V 个数就能找到X,依次找下去就是一个调和级数,最终复杂度O(NlogN)
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+25;
int q,n,v;
int main(){
cin >> q;
while(q--){
cin >> n;
vector<int> ve;
for(int i = 1;i <= n; ++i){
cin >> v; ve.push_back(v);
}
sort(ve.begin(),ve.end());
ve.erase(unique(ve.begin(),ve.end()),ve.end());
int m = (int)ve.size(),ans = 0;
for(int i = 0;i