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

 

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