zoukankan      html  css  js  c++  java
  • CF3D Least Cost Bracket Sequence

    Least Cost Bracket Sequence

    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.

    (nleq 5 imes 10^4).

    题解

    https://ksmeow.moe/lcbs_cf3d_sol/

    解决的方法是使用贪心来做这个题。我们先贪心地让每个"?"变成右括号,当变成右括号时没有左括号与之匹配时,存在两个解决方法:把当前位置变为左括号或把当前位置之前的某一个"?"调整为左括号。实际上这两个问题是同一个问题,从当前位置往前统计所有没变成左括号的"?",并选择变为左括号产生的花费最少的一个转变即可。实现时维护一个存储"?"信息的堆即可选出最小值。

    当最终仍然存在未匹配的左括号或需要左括号却无法产生时,即为无解的情况。

    可以这样思考贪心算法的正确性:在贪心的情境下,问题可以看做将"?"全替换为")",并从原来的"?"位置里选出一些改为"(",并付出一定的花费,求花费最少的能将序列改为完全匹配序列的方案。这两个问题的答案是一致的,因为新问题可以看成原问题中,改成")"的花费为(0)而改成"("的花费为(a_i-b_i)后的问题,最小化后者同时也是最小化前者。每次从一个合法序列末尾放进一个")"时,需要找一个"("与之匹配,这个"("要么已经存在,要么需要从")"变过来,而变过来的时候上述方法实现了最小化。因此上述方法对新问题有正确性,对原问题也有正确性。

    由于堆有每次(O(log n))的操作复杂度,算法总复杂度为(O(nlog n)),且空间为(O(n)),可以通过本题。

    CO int N=5e4+10;
    char s[N];
    priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > pq;
    
    int main(){
    	scanf("%s",s+1);
    	int n=strlen(s+1);
    	int cnt=0;
    	int64 ans=0;
    	for(int i=1;i<=n;++i){
    		if(s[i]=='?'){
    			int a=read<int>(),b=read<int>();
    			s[i]=')';
    			ans+=b,pq.push({a-b,i});
    		}
    		if(cnt==0 and s[i]==')'){
    			if(pq.empty()) {puts("-1"); return 0;}
    			pair<int,int> x=pq.top();pq.pop();
    			s[x.second]='(';
    			if(x.second<i) cnt+=2;
    			ans+=x.first;
    		}
    		cnt+=s[i]=='('?1:-1;
    	}
    	if(cnt!=0) {puts("-1"); return 0;}
    	printf("%lld
    %s",ans,s+1);
    	return 0;
    }
    
  • 相关阅读:
    java之扩展运算符
    error LNK2005: _DllMain@12 已经在 dllmain.obj 中定义
    MinGW
    Gcc/MinGW/Cygwin/Msys 分别是什么?
    开源项目:windows下使用MinGW+msys编译ffmpeg
    MinGW安装和使用基础教程
    基于UDP高性能传输协议UDT doc翻译(一)
    基于UDT connect连接通信以及文件传输--客户端
    基于UDT connect连接通信以及文件传输--服务端
    FreeSWITCH第三方库(其他)的简单介绍(三)
  • 原文地址:https://www.cnblogs.com/autoint/p/12895532.html
Copyright © 2011-2022 走看看