乱搞+暴力+队列优化——B(“1,2,3——4!”)

题目来源


Test On 1.17

出题人:PoPoqqq
2017 年 1 月 17 日


题目描述


“1,2,3——4!”
跳蚤国最近开始排队型来迎接即将到来的跳蚤年啦,跳蚤国王站在主
席台:“队伍怎么这么不整齐??”
跳蚤们站成了一排,参差不齐。为了足够的整齐,国王要求,必须选
出一个当头蚤站在最前面,队伍中所有其他的跳蚤都必须是当头蚤的身高
的整数倍,如果他的高度过于高,就必须学习缩骨功把自己压缩到当头蚤
的身高的整数倍。当然有些跳蚤比当头蚤还矮……很不幸,他们不能再参
与这次排队型活动。
我们定义一个队形的和谐程度为所有跳蚤的高度和,那么最大的和谐
度是多少呢?跳蚤国王当然知道,但是他要考考你……


输入


第一行一个数字 n, 表示一共有 n 个跳蚤。
接下来一行 n 个整数,分别表示 n 个跳蚤的身高。


输出


一个数字,为最大的和谐度。


样例输入


4
15 2 3 9


样例输出


27


样例解释


当然是选萌萌哒的第三号跳蚤作为当头蚤啦,舍弃第二只跳蚤,剩下
两只跳蚤的身高都是第三只的正数倍,能获得的愉悦度是 15 + 3 + 9 = 27


数据规模与约定


对于40%的数据,有n<=1000
对于100%的数据,有n<=10e5, 每个跳蚤的身高<=2*10e5


思路


暴力:

最暴力的方法就是枚举每一个跳蚤作为当头蚤时可获得的和谐度取最大值作为答案

优化:

当高度为x与y(y>=x且y%x==0)同时存在时 以x为当头蚤时可获得的和谐度必然不小于以y为当头蚤时可获得的和谐度(可证,自行想象)

将高度由小到大排序 逐个尝试加入队列 若之前加入队列的高度中有当前高度的因数 则当前高度不加入队列中

最后只要枚举将在队列中的高度作为当头蚤高度时的情况即可


代码(C++)


#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
int n,hei[100010],x,m,ans=0;	bool w;
queue<int> q;
inline void miow();
inline void calc();
int main()
{
	scanf("%d",&n);	
	for(int i=1;i<=n;++i)
		scanf("%d",&hei[i]);
	sort(hei+1,hei+n+1);
	miow();
	calc();
	printf("%d",ans);
	return 0;
}
inline void calc()
{
	x=q.front();
	while(x!=0)
	{
		m=0;
		for(int i=1;i<=n;++i)
			m+=hei[i]-hei[i]%x;
		if(m>ans)
			ans=m;
		q.pop();
		x=q.front();
	}
	return ;
}
inline void miow()
{
	q.push(hei[1]);
	q.push(0);
	for(int i=2;i<=n;++i)
	{
		w=1;	
		x=q.front();
		while(x!=0)
		{
			if(hei[i]%x==0)
				w=0;
			q.pop();
			q.push(x);
			x=q.front();
		}
		q.pop();
		if(w==1)
			q.push(hei[i]);
		q.push(0);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值