Codeforces 990C Bracket Sequences Concatenation Problem

本文介绍了一种算法,用于解决给定多个只包含括号的字符串时,计算能够组合成有效括号序列的不同配对数量的问题。通过预处理字符串来消除相邻匹配的括号对,将问题简化为四种基本情形,并利用哈希映射来统计不同类型的字符串数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A bracket sequence is a string containing only characters "(" and ")".

A regular bracket sequence is a bracket sequence that can be transformed into a correct arithmetic expression by inserting characters "1" and "+" between the original characters of the sequence. For example, bracket sequences "()()", "(())" are regular (the resulting expressions are: "(1)+(1)", "((1+1)+1)"), and ")(" and "(" are not.

You are given n

bracket sequences s1,s2,…,sn. Calculate the number of pairs i,j(1≤i,j≤n) such that the bracket sequence si+sj is a regular bracket sequence. Operation +

means concatenation i.e. "()(" + ")()" = "()()()".

If si+sj

and sj+si are regular bracket sequences and i≠j, then both pairs (i,j) and (j,i) must be counted in the answer. Also, if si+si is a regular bracket sequence, the pair (i,i)

must be counted in the answer.

Input

The first line contains one integer n(1≤n≤3⋅105)

— the number of bracket sequences. The following n lines contain bracket sequences — non-empty strings consisting only of characters "(" and ")". The sum of lengths of all bracket sequences does not exceed 3⋅105

.

Output

In the single line print a single integer — the number of pairs i,j(1≤i,j≤n)

such that the bracket sequence si+sj

is a regular bracket sequence.

Examples

Input

3
)
()
(

Output

2

Input

2
()
()

Output

4

记录一下:卡我初始化。(将s数组开始初始化为0,就一直时间超限)

 

从n个只有 ‘(’  和 ‘)’   的字符串中选出两个,问能组成多少种符合规范的括号,

 只有可能是   两个非完整括号 或 两个完整括号   组合

 

思路:先用栈处理一下字符串,相临的  '('  和  ‘)’  抵消掉,这种()不影响判断是否能和其他串组合成合法字符串。

处理后有四种情况:
1,只有左括号,

2,只有右括号,

3,既有左括号,又有右括号,但左括号在右边,右括号在左边,如:)(

4,什么都没有

1,2种情况 ,可以用map记录,左括号数为负数,右括号数为正数,mp【i】,右括号有i个的字符串的个数

3,   直接统计此类型的个数  

4,作废

 

该非完整括号的字符串个数 乘 能与之配对的字符串的个数 + 完整括号的个数的平方    \binom{n}{2}*{A{__2}^{_2}}+n = n^{2}

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <stack>
#include <queue>
#include <deque>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-8
#define PI acos(-1)
#define INF 0x3f3f3f3f
#define N 500000 + 10
using namespace std;
const int intN = 3e5 + 10 ;
typedef long long int LL;
const int dir[4][2]= { {1,0},{0,1},{-1,0},{0,-1} };

int GCD(int a,int b)
{
    return b ? GCD(b,a%b) : a;
}
int cmp(int a,int b)
{
    return a>b;
}

int main()
{
    stack<char>p;
    map<int,LL>mp;
    map<int,LL>::iterator it;
    LL i,m=0,t,j,ans=0;
    scanf("%lld",&t);
    getchar();
    for(j=0; j<t; j++)
    {
        char s[N];
        gets(s);
        for(i=0; s[i]; i++)
        {
            if(!p.empty())
            {
                if(p.top()=='(' && s[i]==')')
                    p.pop();
                else
                    p.push(s[i]);
            }
            else
                p.push(s[i]);
        }
        if(p.empty())
            m++;
        else
        {
            int lchar=0,rchar=0;
            while(!p.empty())
            {
                if(p.top()=='(')
                    lchar++;
                else if(p.top()==')')
                    rchar++;
                p.pop();
            }
            if(lchar!=0 && rchar==0)
                mp[-lchar]++;
            else if(lchar==0 && rchar!=0)
                mp[rchar]++;
        }
    }
    for(it=mp.begin(); it!=mp.end(); it++)
    {
        if(mp.find( (it->first)*(-1) )!=mp.end() )
        {
            ans+=it->second*mp[it->first*-1];
            mp[it->first*-1]=0;
        }
    }
    printf("%lld\n",ans+m*m);
    return 0;
}

 

### 关于 Codeforces 上二项装箱问题 #### 二项装箱问题概述 二项装箱问题是经典的组合优化问题之一,在计算机科学领域具有重要意义。该类问题通常涉及将一组不同大小的对象放入固定容量的容器中,目标是最小化使用的容器数量[^1]。 对于特定平台上的挑战实例,如Codeforces中的二项装箱问题,其核心在于设计高效算法来解决这一NP难问题。尽管找到最优解可能非常复杂,但存在多种启发式方法可以提供接近最佳的结果,并且这些方法能够在合理的时间内执行完毕。 #### 解决方案策略 一种常见的处理方式是采用贪心算法,即总是尝试把当前最大的未分配物品放置到第一个能够容纳它的箱子中;如果没有任何现有箱子能放下这件物品,则创建一个新的箱子用于装载它。这种方法简单易懂,但在某些情况下可能会导致次优解。 更复杂的近似算法包括首次适应下降(First Fit Decreasing, FFD),此技术首先按照降序排列所有项目尺寸,之后应用首次适配原则(FD)。FFD已被证明能在多项式时间内给出不超过理想最小值11/9倍数加四的解法质量保证[^2]。 此外还有其他高级求解途径比如动态规划、分支限界以及遗传算法等,它们各自适用于不同的应用场景并提供了不同程度上的性能改进。 ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int n; cin >> n; vector<int> items(n); for(int i = 0; i < n; ++i){ cin >> items[i]; } sort(items.begin(), items.end(), greater<int>()); const int bin_capacity = 1000; // 假设每个bin的最大容量为1000单位体积 vector<int> bins; for(auto item : items){ bool placed = false; for(auto& b : bins){ if(b + item <= bin_capacity){ b += item; placed = true; break; } } if(!placed){ bins.push_back(item); } } cout << "Minimum number of bins required is: " << bins.size(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值