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

    题目

    原题地址

    解说

    被自己选的题卡了两节课……
    首先,问号的状态会影响能否匹配,那么我们不妨就先让所有问号都为右括号,什么时候右括号太多了就把前面的问号改成左括号即可。
    那么前面有多个问号的时候我们应该选择哪个?显然我们应该运用贪心思想,哪个问号改变后为我们减少的花费多我们就选哪个,这就需要我们维护一个优先队列,排序的依据是(-b+a)的大小((b)是该问号改为右括号的价值,(a)是该问号改为左括号的价值)。我们每遇到一个问号就把它推进队列里,以备之后选用。每选用一个括号就把它改为左括号,同时修改我们的(answer)和计数器。
    当然,在这个过程中我们还需要判断能否匹配。不匹配的情况总共两种:
    1.发现右括号比左括号还多后前面却没有问号用来抵消
    2.到最后发现左括号比右括号和问号的和还多
    这时输出(-1)即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=50000+3;
    typedef long long ll;
    char s[maxn];
    struct inf{//记录问号的位置和价值
    	int loc;
    	ll a,b;
    	inf(int d,ll e,ll f){
    		loc=d; a=e; b=f;
    	}
    	bool operator<(const inf &x)const{//排序依据
    		return -b+a>-x.b+x.a;
    	}
    };
    priority_queue<inf> q;
    int main(){
    	scanf("%s",s);
    	int len=strlen(s),js=0;//js为计数器
    	ll ans=0;
    	for(int i=0;i<len;i++){
    		if(s[i]=='(') js++;
    		if(s[i]==')') js--;
    		if(s[i]=='?'){
    			js--;
    			ll a,b;
    			scanf("%lld%lld",&a,&b);
    			q.push(inf(i,a,b));
    			ans+=b;//默认为右括号
    			s[i]=')';
    		}
    		if(js<0){//右括号太多了
    			if(q.empty()){//解说里输出-1的情况一
    				printf("-1");
    				return 0;
    			}
    			inf k=q.top();
    			ans=ans-k.b+k.a;//改为左括号
    			js+=2;
    			q.pop();
    			s[k.loc]='(';
    		}
    	}
    	if(js!=0){//解说里输出-1的情况二
    		printf("-1");
    		return 0;
    	}
    	printf("%lld
    ",ans);
    	printf("%s",s);
    	return 0;
    } 
    

    幸甚至哉,歌以咏志。

  • 相关阅读:
    看过的代码
    ScipyLectures-simple学习笔记
    机器学习1一个月2017/11/24-2017/12/24
    机器学习课程 matlab 练习
    win7 win8 快捷键直接调出任务管理器
    java 关于getProperty()方法中反斜杠问题
    把myeclipse中html/jsp文件的视图调到只看代码
    Win7 server2008 共享文件夹 不输入网络密码
    别用visual editor了,用WindowBuilder
    visual editor ve1.5下载
  • 原文地址:https://www.cnblogs.com/DarthVictor/p/12906165.html
Copyright © 2011-2022 走看看