P6786 「SWTR-6」GCDs & LCMs

题目描述

小 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;
}

猜你喜欢

转载自blog.csdn.net/weixin_49843717/article/details/108433521