贪心 Pavel and Triangles三角形

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

He has a0 sticks of length 20=1, a1sticks of length 21=2, …, a_n−1_sticks of length 2n−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 n (1≤n≤300000) — the number of different lengths of sticks.

The second line contains n integers a0, a1, …, an−1 (1≤ai≤109), where ai is the number of sticks with the length equal to 2i.

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), (21,23,23), (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), (21,21,21), (22,22,22).

历程:今天晚上一直在搞这个题目,我真的有点操蛋了,我还承诺要实现愿望呢,别懈怠呀,笨蛋!

有感启发:这道题目是贪心的题目,我也想到了,但是不知道该怎么贪心啊啊啊。今天晚上的题又是格外的难,还有好几个没有参加比赛,一个大四的学长一直说我们懒,我最近可能真的有点懈怠了,自己认真想一下,最近晚上都在2点多睡觉,但是我差不多在十二点多就上床睡觉了,自己一直在那玩手机啥的,有啥好玩的呢,每天都在看,也没看出点啥的,但是结果就是浪费了时间,导致明天早晨10多起床,起来的时候还要玩一会手机。每天玩手机的时间都快超4个小时了,这个时间用来学习不好吗,后边每天要控制玩手机的时间,要休息就睡觉,起来就学习,学累了就听会音乐,坚持一个月,一个月回来我再看看效果,后边晚上睡觉就不玩手机了!

思路:首先先将前边剩下的单独的个体先与后边加进来的点组成三角形,然后在考虑剩下的点每三个组成三角形。

证明:首先先假设前边的树枝已经构成了最优解,再新加入一类树枝,按照数量分成两类:一类是数量大于等于2 的树枝,一类是数量小于2 的树枝,数量小于二的树枝没得说,不能进行任何操作。看树枝数量大于二的,我们明白所有的树枝的数量是一定的,那么只要满足剩下的树枝数目最小即可,我们将前边剩下的树枝不妨叫一个名字:无用树枝,因为要想消除他们只能靠后边相同的两根树枝,我们如果在新加入的一类树枝中选择两个与前边剩下的树枝进行重组,并且这个操作与最优解操作不相符,那么我们就相当于在新加入的这类树枝中多产生了一个无用的树枝,但是由于我们将前边无用的树枝进行了重组,前边无用的树枝减少了一根,那就意味值我们的最优解与我们贪心答案是相同的,至此,证毕。

代码:

#include <iostream>

using namespace std;

typedef long long LL;

int main()
{
    int n; scanf("%d", &n);
    LL res = 0, k = 0;
    for (int i = 1; i <= n; i ++)
    {
        LL a; scanf("%lld", &a);
        int t = min(k, a / 2);
        
        if (t == k) a -= k * 2, res += k + a / 3, k = 0;
        else k -= a / 2, res += a / 2, a -= a / 2 * 2; 

        k += a % 3;
    }
    printf("%lld", res);
}

感谢一路上帮助我、鞭策我前行的人,我知道完成这很难,但我会努力的!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值