C. Compressed Bracket Sequence

William has a favorite bracket sequence. Since his favorite sequence is quite big he provided it to you as a sequence of positive integers c1,c2,…,cnc1,c2,…,cn where cici is the number of consecutive brackets "(" if ii is an odd number or the number of consecutive brackets ")" if ii is an even number.

For example for a bracket sequence "((())()))" a corresponding sequence of numbers is [3,2,1,3][3,2,1,3].

You need to find the total number of continuous subsequences (subsegments) [l,r][l,r] (l≤rl≤r) of the original bracket sequence, which are regular bracket sequences.

A bracket sequence is called regular if it is possible to obtain correct arithmetic expression by inserting characters "+" and "1" into this sequence. For example, sequences "(())()", "()" and "(()(()))" are regular, while ")(", "(()" and "(()))(" are not.

Input

The first line contains a single integer nn (1≤n≤1000)(1≤n≤1000), the size of the compressed sequence.

The second line contains a sequence of integers c1,c2,…,cnc1,c2,…,cn (1≤ci≤109)(1≤ci≤109), the compressed sequence.

Output

Output a single integer — the total number of subsegments of the original bracket sequence, which are regular bracket sequences.

It can be proved that the answer fits in the signed 64-bit integer data type.

input

5
4 1 2 3 1

output

5

input

6
1 3 2 1 2 4

output

6

input

6
1 1 1 1 2 2

output

7

题意:给出一个长度为n的数组,要求组成正确的括号序列,奇数位置代表该位置有a[i]个左括号,偶数位置代表右括号

题解:其实就是括号匹配,我用的n方的算法,枚举每个左边界,然后向右拓展。具体思路是当前剩下的左括号如果不为负数就继续向后匹配,当后面的右括号大于等于左括号时,我们让他和之前剩下的左括号进行匹配。

#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<deque>
#include<cstring>
#include<vector>
#include<set>
#include<cmath>
#include<cstring>
#include<cstdlib>
#define fi first
#define se second
#define u1 (u<<1)
#define u2 (u<<1|1)
#define PII pair<int,int>
#define ll long long
#define ull unsigned long long
#define PLL pair<long long,long long>
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scl(a) scanf("%lld",&a)
#define rep(i,n) for(int i = 0; (i)<(n); i++)
#define rep1(i,n) for(int i = 1; (i)<=(n); i++)
#define pb(a) push_back(a)
#define mst(a,b) memset(a, b, sizeof a)
#define ac cout<<ans<<endl
using namespace std;
const int N=1e4+10;
ll ans;
ll a[N];
ll last[N];
ll qianzui[N];
void solve()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    if(n%2) n--;
    for(int i=1;i+1<=n;i+=2){
        if(a[i]<a[i+1]) ans+=a[i];  //如果左括号没剩下就不继续向后找
        else{
            ans+=a[i+1];
            ll last=a[i]-a[i+1];        //last表示剩下的左括号
            ll now=0;                 //now表示右边新来的括号的右括号数量
            for(int j=i+2;j+1<=n;j+=2)
            {
                now+=a[j+1]-a[j];          //枚举右边来的括号能不能组成一个右括号大于等于左括号的序列
                if(now>=0){             //如果新来的可以了
                    ans+=min(now,last)+1;   //加上答案数
                    last-=now;         //左括号减少
                    if(last<0) break;   //如果左括号全没了,就不继续向后找
                    now=0;              //把右边的都归进左边了,右边清零
                }
            }
        }
    }

    ac;
}
signed main()
{
    int t=1;
    //scd(t);
    while(t--) solve();
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值