Codeforces Global Round 2 E. Pavel and Triangles

E. Pavel and Triangles
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Pavel has several sticks with lengths equal to powers of two.

He has a0 sticks of length 20=1, a1 sticks of length 21=2, …, an−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
inputCopy
5
1 2 2 2 2
outputCopy
3
inputCopy
3
1 1 1
outputCopy
0
inputCopy
3
3 3 3
outputCopy
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).

题目是说给你n个数,你可以进行两种操作,一种是把一个数减去3,另一种是把对任意的i<j,把ai减去1,把aj减去2。但所有的数都不能减到小于0。
用两个变量,ans记录答案,cnt记录我们选了多少个当前减2,前面任选一个减1。我们考虑从后往前贪心,如果当前值为1,那么如果cnt有值,那么我们就–cnt,++ans。否则,如果当前值ai是偶数,那么我们拿走ai/2个2,也就是cnt+=ai/2,ans+=ai/2,如果当前值ai是奇数,那么我们先拿走一个3,也就是++ans,ai-=3,然后ai就变成了偶数,就按照之前描述的操作。贪心完了以后我们发现我们还需要拿走cnt个1,但我们现在已经把所有的ai清零了,所以我们得从ans里面扣除一部分将cnt补成负数,因为一次操作会使整个数组的所有数之和减3,也就是说–ans可以让cnt-=3,我们将需要减去的cnt减去即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 5;
typedef long long ll;
ll ans,cnt;
int z[maxn];
int n;
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i)
        scanf("%d", z + i);
    for (int i = n; i >= 1; --i)
    {
        if (z[i] % 2 == 0)
        {
            ans += z[i] / 2;
            cnt += z[i] / 2;
        }
        else if (z[i] == 1)
        {
            if (cnt)
                --cnt;
        }
        else
        {
            ++ans;
            z[i] -= 3;
            ans += z[i] / 2;
            cnt += z[i] / 2;
        }
    }
    if (cnt)
        ans -= (cnt + 2) / 3;
    printf("%lld\n", ans);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章