C. Compressed Bracket Sequence
不得不说师弟确实强,先贴一下他的代码(还没开学的大一新生师弟
思路:
核心思想就是计算贡献
sum数组是用来计算连续的匹配括号对产生的贡献
假设有三个整体,整体就是
(
(
(
)
)
)
,
(
(
)
)
,
(
)
((())),(()),()
((())),(()),() 这样的,为了简化我设成
(
)
(
)
(
)
()()()
()()() 这样的三个整体
由于它自己产生的贡献我们已经计算过,现在考虑整体之前结合产生的贡献,
(
)
(
)
,
(
)
(
)
,
(
)
(
)
(
)
()(),()(),()()()
()(),()(),()()(),这三种情况贡献为
3
3
3,然后如果又连接了一个整体
(
)
()
(),那么现在有
(
)
(
)
,
(
)
(
)
,
(
)
(
)
,
(
)
(
)
(
)
,
(
)
(
)
(
)
,
(
)
(
)
(
)
(
)
()(),()(),()(),()()(),()()(),()()()()
()(),()(),()(),()()(),()()(),()()()() 这
6
6
6 个情况,贡献为
6
6
6,那么比之前多了
3
3
3 ,所以
a
n
s
+
=
a
[
j
]
+
s
u
m
[
j
−
1
]
ans += a[j] + sum[j-1]
ans+=a[j]+sum[j−1],
a
n
s
+
=
t
o
t
+
s
u
m
[
j
−
1
]
ans += tot + sum[j-1]
ans+=tot+sum[j−1] 中的
s
u
m
[
j
−
1
]
sum[j-1]
sum[j−1] 就是连续的整体产生的贡献,而当
t
o
t
=
a
[
j
]
tot=a[j]
tot=a[j] 时,恰好完成了匹配,没有剩余,就可以和前一个整体形成匹配,
s
u
m
[
i
]
=
s
u
m
[
j
−
1
]
+
1
sum[i]=sum[j-1]+1
sum[i]=sum[j−1]+1,而不是
t
o
t
<
a
[
j
]
tot < a[j]
tot<a[j] 时的
s
u
m
[
i
]
+
+
sum[i]++
sum[i]++。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int a[N];
long long sum[N];
int main()
{
int n; scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
long long ans = 0;
for(int i = 2; i <= n; i += 2)
{
int tot = a[i];// 右括号数量
for(int j = i - 1; j >= 1; j -= 2)// 试图和左边的左括号匹配
{
if(!tot) break;
if(!a[j]) continue;
if(tot < a[j])// 右括号可以匹配 这次匹配完就用光了
{
ans += tot;
a[j] -= tot;
sum[i]++;break;// tot 个括号对算一个整体,如果有连续的括号对也会有贡献
}
if(tot == a[j])
{
ans += tot + sum[j - 1];
sum[i] = 1 + sum[j - 1];
a[j] = 0;break;
}
// tot > a[j]
tot -= a[j]; // 不断往左匹配左括号
ans += a[j] + sum[j - 1];
a[j] = 0;
}
}
printf("%lld",ans);
return 0;
}