D. Least Cost Bracket Sequence (贪心)

针对一个包含左括号、右括号及问号的序列,通过替换问号以最小化总成本并确保括号配对正确。采用贪心策略,记录成本并调整以满足配对条件。

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

点击打开链接

http://codeforces.com/contest/3/problem/D

D. Least Cost Bracket Sequence

Description:

This is yet another problem on regular bracket sequences.

A bracket sequence is called regular, if by inserting "+" and "1" into it we get a correct mathematical expression. For example, sequences "(())()", "()" and "(()(()))" are regular, while ")(", "(()" and "(()))(" are not. You have a pattern of a bracket sequence that consists of characters "(", ")" and "?". You have to replace each character "?" with a bracket so, that you get a regular bracket sequence.

For each character "?" the cost of its replacement with "(" and ")" is given. Among all the possible variants your should choose the cheapest.

Input

The first line contains a non-empty pattern of even length, consisting of characters "(", ")" and "?". Its length doesn't exceed 5·104. Then there follow m lines, where m is the number of characters "?" in the pattern. Each line contains two integer numbers ai and bi (1 ≤ ai,  bi ≤ 106), where ai is the cost of replacing the i-th character "?" with an opening bracket, and bi — with a closing one.

Output

Print the cost of the optimal regular bracket sequence in the first line, and the required sequence in the second.

Print -1, if there is no answer. If the answer is not unique, print any of them.

Examples
input
(??)
1 2
2 8
output
4
()()

题意:

给你一个序列,序列里面有左括号,右括号。对于一个“?”,可以替换成“(”,“)”,替换的代价为a_i,b_i。

问你如何替换使得代价最小。前提是替换之后的序列中,括号是匹配的。如果不能替换为一个括号匹配的序列则输出-1。

解释样例:

对于第一个括号,那就替换成“)”,代价为2。

对于第二个括号,那就替换成“(”,代价为2。

所以最少总代价为2+2=4。

题解:贪心。

每遇到一个‘?’,就替换成右括号,并维护一个计数器count,当遇到左括号时计数器+1,遇到右括号时计数器-1。如果中途遇到count小于0的情况,则说明这个序列不是括号匹配的,而多余的右括号可能是‘?’变来的,所以当遇到count小于0时,则去看前面有没有‘?’变过来的右括号,如果没有,那就说明无论如何这个序列无法被替换为括号匹配的序列;如果有的话,则选取一个花费最少代价变来的右括号,将其改为左括号,这样的话count就要加2了。如果这样到最后count还大于0,则说明即使无法获得一个括号匹配的序列,输出-1即可。


AC代码:

#include<bits/stdc++.h>
using namespace std;
const int maxx=50010;
char s[maxx];
set<pair<long long,int> >st;
int main()
{
    scanf("%s",s);
    long long count=0,ans=0;
    for(int i=0;s[i];i++)
    {
        if(s[i]=='(')count++;
        else if(s[i]==')')count--;
        else
        {
            int a,b;
            cin>>a>>b;
            ans+=b;
            s[i]=')';
            count--;
            st.insert(make_pair(a-b,i));
        }
        while(count<0)
        {
            if(st.empty())return 0*printf("-1");
            ans+=st.begin()->first;
            s[st.begin()->second]='(';
            st.erase(st.begin());
            count+=2;
        }
    }
    if(count>0)printf("-1");
    else printf("%lld\n%s",ans,s);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值