Compressed Bracket Sequence(模拟)

题目

Compressed Bracket Sequence


问题描述

原来的序列是一个括号序列,此时给出它的压缩序列, “ ( ( ( ( ) ( ( ) ) ) ( ” “(((()(()))(” (((()(()))(对应的压缩序列是 [ 4 , 1 , 2 , 3 , 1 ] [4,1,2,3,1] [4,1,2,3,1],问在给定压缩序列的前提下,求出匹配序列的个数。
例子:
压缩序列为 [ 4 , 1 , 2 , 3 , 1 ] [4,1,2,3,1] [4,1,2,3,1]时,匹配序列为5,
从第3个到第10个字符的子序列:(()(()))
从第4个字符到第5个字符的子序列:()
从第4个字符到第9个字符的子序列:()(())
从第6个字符到第9个字符的子序列:(())
从第7个字符到第8个字符的子序列:()


分析

这道题的思路就是模拟。

首先分析题目,如果从0开始计数,偶数位置对应的是左括号,奇数位置对应的就是右括号,根据题目,其实我们可以把相邻的位置理解为一个对,比如在压缩序列 [ 4 , 1 , 2 , 3 , 1 ] [4,1,2,3,1] [4,1,2,3,1]中,可以把 [ 4 , 1 ] [4,1] [4,1]理解为一个对,把 [ 2 , 3 ] [2,3] [2,3]理解为另一个对,最后多余的 [ 1 ] [1] [1]是无法找到匹配的,所以舍弃。

接下来我们就处理一下序列 [ [ 4 , 1 ] , [ 2 , 3 ] ] [[4,1],[2,3]] [[4,1][2,3]]

先处理 [ 4 , 1 ] [4,1] [4,1],4>1,这里只有一种匹配序列,而且 [ 4 , 1 ] [4,1] [4,1]左边没有对了,所以不存在向左边延伸的情况;

再处理 [ 2 , 3 ] [2,3] [2,3],在对内部有两种匹配序列,同时可以发现,在这一对里面多了一个右括号,而且左边仍然有对,所以可以考虑向左边延伸的情况。
想要延伸到左边,就意味着左边的对的左括号数目一定要大于等于右括号才可以相连,然后再考虑左边的对的左括号数目,确定匹配个数,当前左边的对为 [ 4 , 1 ] [4,1] [4,1],如果不使用多余左括号,存在一种匹配序列,在考虑多余左括号,多出3个,但此时 [ 2 , 3 ] [2,3] [2,3]右括号只多出1个,所以接下来还剩一种匹配序列。
之后,不再存在右括号剩余,故不必再左移。

总计5种匹配序列。

代码

#include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
const int MAXN = 1005;
int C[MAXN];
int N;
 
int main() {
    cin>>N;
    for(int i=0;i<N;i++){
    	cin>>C[i];
	}
	
    ll cnt = 0;
    for (int j = 1; j < N; j += 2) {
        ll h = 0;
        ll internal = -C[j];
        for (int i = j-1; i >= 0; i -= 2) {
            h += C[i+1];//总共剩余的右括号
            internal += C[i+1];//当前对的右括号
            if (C[i] > h) {
                cnt += h - internal;
                if (internal) ++cnt;
                break;
            }
            if (C[i] >= internal) {
                cnt += C[i] - internal;
                if (internal) ++cnt;
            }
            internal -= min((ll)C[i], internal);
            h -= C[i];
        }
    }
    cout<<cnt<<endl;
    return 0;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值