Codeforces Global Round 2 E Pavel and Triangles

http://codeforces.com/contest/1119/problem/E

Pavel has several sticks with lengths equal to powers of two.

He has a0a0 sticks of length 20=120=1 , a1a1 sticks of length 21=221=2 , ..., an−1an−1 sticks of length 2n−12n−1 .

Pavel wants to make the maximum possible number of triangles using these sticks. The triangles should have strictly positive area, each stick can be used in at most one triangle.

It is forbidden to break sticks, and each triangle should consist of exactly three sticks.

Find the maximum possible number of triangles.

Input

The first line contains a single integer nn (1≤n≤3000001≤n≤300000 ) — the number of different lengths of sticks.

The second line contains nn integers a0a0 , a1a1 , ..., an−1an−1 (1≤ai≤1091≤ai≤109 ), where aiai is the number of sticks with the length equal to 2i2i .

Output

Print a single integer — the maximum possible number of non-degenerate triangles that Pavel can make.

Examples

Input

5
1 2 2 2 2

Output

3

Input

3
1 1 1

Output

0

Input

3
3 3 3

Output

3

Note

In the first example, Pavel can, for example, make this set of triangles (the lengths of the sides of the triangles are listed): (20,24,24)(20,24,24) , (21,23,23)(21,23,23) , (21,22,22)(21,22,22) .

In the second example, Pavel cannot make a single triangle.

In the third example, Pavel can, for example, create this set of triangles (the lengths of the sides of the triangles are listed): (20,20,20)(20,20,20) , (21,21,21)(21,21,21) , (22,22,22)(22,22,22) .

题目大意:你有n种木棍,其长度分别为:1、2、4……2^(n-1),现给出每种木棍的个数,问最多能组成多少个三角形。

思路: 贪心,三角形只有两种形式:(1)三边长度相同;(2)一条短边,两条相等的长边。(举个例子 2+2=4 2+4=6<8 所以其他情况是不行的) 贪心思想:从没用完的短木棍中取1个,从当前的长木棍中取2个组成一个三角形,直到短木棍用完或长木棍用完。 若短木棍用完了长木棍剩余数量>=3,则长木棍3个3个内耗掉,剩余的加入到短木棍中。(因为下次迭代 这个木棍就相当于短木棍了 不用担心3个3个内耗是否会对后续产生影响 因为下一个木棍也可以通过这种形式 我们的思想是尽量把木棍都用完 这样肯定是最优解)

#include<iostream>
#include<cstdio>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

int a[300005];
int n;

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)//两个大的+1个小的
		scanf("%d",&a[i]);
	ll ans=0;
	ll cur=0;
	for(int i=0;i<n;i++)
	{
		int temp=min(cur,(ll)a[i]/2);//当前剩下的小的个数 与大的个数的一半 取最小值
		cur-=temp;	//消耗掉temp个小的
		a[i]-=temp*2;	//消耗掉 2*temp 个大的
		ans+=temp;//对答案的贡献
		ans+=a[i]/3;
		a[i]%=3;
		cur+=a[i];
	}
	printf("%lld\n",ans);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值