Least Cost Bracket Sequence 思维

分析

看到括号匹配,先开个栈
这题感觉还是不错的
首先需要知道代价最小的前提是括号序列合法,所以不能单纯的贪心代价小的放法。
对于一个合法的序列来说,左右括号的数量一定相等,并且在当前位置,左括号的数量一定不小于右括号的数量,于是可以开一个栈来存左括号,遇到右括号就弹栈,栈空则不合法。
其实对于这道题来说没必要开一个栈,留下一个栈顶就可以,因为它栈里的元素都是一样的。
然后就可以考虑贪心了,扫描整个序列,如果是问号,就替换成右括号,然后判断能不能配对,这样的结果一定是正确的,因为左括号的数量一定不小于右括号的数量,所以在右括号数量多于左括号时,取出左括号代价最少的那个就行,这样每一步都保证了当前括号序列是合法并且最优,所以可行。

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node{
	int val,idx;
	Node(){}
	Node(int a,int b){
		val=a;idx=b;
	}
	bool operator<(const Node &A)const{
		return val>A.val;
	}
};
priority_queue<Node > que;
char s[50002];
int top;long long ans;
int main(){
	scanf("%s",s);
	int l=strlen(s);
	for(int i=0;i<l;i++){
		if(s[i]=='(')top++;
		else {
			top--;
			if(s[i]=='?'){
				int a,b;
				scanf("%d%d",&a,&b);
				que.push(Node(a-b,i));
				s[i]=')';
				ans+=b;
			}
		}
		if(top<0){
			if(que.empty())
				return printf("-1\n"),0;
			top+=2;
			Node u=que.top();que.pop();
			s[u.idx]='(';
			ans+=u.val;
		}
	}
	if(top||ans==-1)
		printf("-1\n");
	else printf("%lld\n%s",ans,s);
}

猜你喜欢

转载自www.cnblogs.com/anyixing-fly/p/12906224.html