C. Compressed Bracket Sequence(括号匹配)

Problem - C - Codeforces

威廉有一个最喜欢的括号序列。由于他最喜欢的序列相当大,他将其作为正整数序列C1, C2, ., Cn提供给你,其中c是连续括号的个数”(“如果i是奇数或连续括号的个数”)“如果I是偶数。例如,对于括号序列“((())())”,对应的数字序列为[3, 2,1,3].您需要找到连续子序列(子段)的总数[2,r] (l <正则括号序列。R)的原始括号序列,即如果在括号序列中插入字符“+”和“1”,可以得到正确的算术表达式,则称为正则括号序列。例如,序列  "(())()","()" 和  "(() (()))" 是常规,而  ") (", "(()" 和  "(())) (" 不是。输入第一行包含一个整数n (1 <n 1000),即压缩序列的大小。第二行包含一个整数序列C1, C2,..,Cn (1 <c < 10°)为压缩序列。输出输出一个整数,表示原始括号序列的子段总数,这些子段是规则的括号序列。可以证明答案符合带符号的64位整数数据类型。

Examples

input

Copy

5
4 1 2 3 1

output

Copy

5

input

Copy

6
1 3 2 1 2 4

output

Copy

6

input

Copy

6
1 1 1 1 2 2

output

Copy

7

请注意在第一个示例中,描述了sequence()))(。此括号序列包含5个子段,它们构成规则的括号序列:1. 从第3个字符到第10个字符的子序列:(()(()))2. 从第4到第5个字符的子序列:()3.第4到第9个字符的子序列:()(())4. 从第6到第9个字符的子序列:(())5. 从第7到第8个字符的子序列:()在第二个示例中,描述了sequence()))(()()))))。在第三个例子中,描述了sequence()()(())。

题解:
数据范围只有1000,我们直接暴力枚举左边界,把左边界多余的与右边多余的匹配,n^2的复杂度

具体细节在代码中均有注释

#include<iostream>
#include<string>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
typedef long long ll;
#define int long long
typedef pair<int,int> PII;
int a[1005];
void solve()
{
	int n;
	cin >> n;
	for(int i = 1;i <= n;i++)
	{
		cin >> a[i];
	}
	if(n % 2)
	n--;//奇数位为(
	int ans = 0;
	for(int i = 1;i + 1 <= n;i += 2)
	{
		if(a[i] < a[i+1])
		{
			ans += a[i];小于第一个右括号数量,只能匹配左括号数量那么多
		}
		else
		{
			ans += a[i + 1];
			int last = a[i] - a[i + 1];//记录多余的右括号数量
			int now = 0;
			for(int j = i + 2;j + 1<=n;j += 2)
			{
				now += a[j + 1] - a[j];//记录多余的左括号数量
				if(now >= 0)
				{
					ans += min(now,last) + 1;//为啥这里要加1下面有图解
					last -= now;
					if(last < 0)
					break;
					now = 0;
				}
			}
		}
	}
	cout << ans;
}
signed main() 
{
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
	int t = 1;
//	cin >> t;
//    scanf("%lld",&t);
	while (t--) 
	{
		solve();
	}
	return 0;
}

本身右边一些 

已经能匹配的算一种 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值