CF1556C Compressed Bracket Sequence题解
纪念拿到最优解,写一篇题解。
首先这题我们有一个很显然的想法:设一个
但这样有一种情况我们就会算漏。考虑这样一个括号序列
为社么会错呢?因为我们在用上面算法的时候默认计算的序列都是首尾配对的即类似
那么设
那么这道题就做完了,接下来是代码时间
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e3+5;
ll ans,f[maxn];
int n,tot;
int c[maxn],st[maxn];//开个栈来记录还有左括号的位置
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&c[i]);
for(int i=1;i<=n;i++){
if(i&1)
st[++tot]=i;
else{
int las=0;
for(int j=tot;j>=1;j--){
if(c[i]>=c[st[j]]){
las=st[j]-1;//las会被不断更新,直到c[i]被减到0。
ans+=c[st[j]]+f[st[j]-1];
c[i]-=c[st[j]];
c[st[j]]=0;
--tot;
}
else{
ans+=c[i];
c[st[j]]-=c[i];
c[i]=las=0;//如果在匹配的时候,pre还有i没了,此时不能从f[las]转移过来
if(!c[st[j]])
--tot;
break;
}
if(!c[i])
break;
}
if(!c[i])
f[i]=f[las]+1;//如果右括号都用完了就更新f
}
}
printf("%lld\n",ans);
return 0;
}