P3015 [USACO11FEB]最好的括号Best Parenthesis

P3015 [USACO11FEB]最好的括号Best Parenthesis

题解

一定要开 long long !!!

                

通过阅读英文题面我们知道所给出的字符串是已经匹配好的,所以我们只是计算就好了

考虑栈模拟实现,每一个括号都视作一层

设数组 s[ i ] 为栈中第 i 层左括号所积累的得分

(1)当输入0,也就是入栈一个左括号,那么我们s[ ]数组就往下开拓新的一层

(2)当输入1,也就是入栈一个右括号,当前层为右括号,此时有两种情况:

         <1>  上一层的左括号本身没有得分,也就是我们当前的右括号与最近的也就是上一层的左括号匹配,凑出一个(这样的括号,所以把上一层的左括号出栈,它的贡献值为1,添加到上上层的左括号里(因为上上层左括号可能本身就有得分),有:

         <2> 上一层的左括号本身有得分,实际上我们当前的右括号并不是与最近的也就是上一层的左括号匹配,而是与上上层的括号匹配,即我们得到 ((括号套括号(灰色括号代表已经出栈消掉了),所以内部括号得分*2添加到上上一层左括号里,有:

 注意上一层的左括号出栈时候清空其得分

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<queue>

using namespace std;

typedef long long ll;

inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

const int maxn=1e5+10;
const ll mod=12345678910;
int x,n;
ll s[maxn],top=0;

int main()
{
    n=read();
    for(int i=1;i<=n;i++){
        x=read();
        if(!x) top++;
        else{
            if(s[top]==0) s[top-1]=(s[top-1]+1)%mod,top--;
            else{
                s[top-1]=(s[top-1]+s[top]*2)%mod,s[top]=0,top--;
            }
        }
    }
    printf("%lld
",s[0]);
    return 0;
}
原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11923259.html