题目描述
小 A 有一个长度为 nn 的序列 a_1,a_2,a_n他想从这些数中选出一些数 b_1,b_2,b_k 满足:对于所有 i (1≤i≤k),b_i 要么是序列 b 中的最大值,要么存在一个位置 j 使得 b_j>b_i 且
b i + b j + g c d ( b i , b j ) = l c m ( b i , b j ) 。 b_i+b_j+gcd(b_i,b_j)=lcm(b_i,b_j)。 bi+bj+gcd(bi,bj)=lcm(bi,bj)。
如果你不知道 gcd 和 lcm 是什么,可以点击最底部的「帮助/提示」部分的链接。
小 A 想让选出的数之和尽量大。请求出这个最大值。
输入格式
第一行一个整数 n,表示序列的长度。
第二行 n 个整数 a_1,a_2,a_n。
输出格式
输出一行一个整数表示答案。
思路
由于我数学不太好所以在经过了大量的尝试后,发现2个数满足题目条件当且仅当较小的数*3/2=较大的数时才成立(所以较小的数只能是偶数),那么我们只需要枚举每一种情况就行了
code:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
map<int,int> a2;
int n,a[300005];
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
a2[a[i]]++;
}
sort(a+1,a+n+1);
long long mx=0;
for (int i=1;i<=n;i++)
{
long long j=a[i];
long long s=0;
while (a2[j]!=0)
{
long long k=a2[j],k2=j*k;
s=s+k2;
a2[j]=0;
if (j%2==0) j=j/2*3;
else break;
}
mx=max(s,mx);
}
cout<<mx;
return 0;
}