• 51nod1476 括号序列的最小代价


    这题应该可以用费用流写吧?不过我想不出贪心来TAT。其实还是单调队列乱搞啊T_T

    //ÍøÉϵÄÌ°ÐÄËã·¨ºÃÉñ°¡¡£¡£¡£ÎÒÖ»»áÓÃ×îС·ÑÓÃ×î´óÁ÷ÅÜTAT 
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<queue>
    using namespace std; 
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define clr(x,c) memset(x,c,sizeof(x))
    int read(){
    	int x=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return x;
    }
    priority_queue<int>q;
    const int nmax=5e4+5;
    const int inf=0x7f7f7f7f;
    int a[nmax];char s[nmax];
    int main(){
    	scanf("%s",s+1);
    	int n=strlen(s+1),u,v,cnt=0;long long sm=0;
    	rep(i,1,n) if(s[i]=='?') u=read(),v=read(),sm+=v,a[i]=v-u;
    	rep(i,1,n){
    		if(s[i]=='(') ++cnt;else --cnt;
    		if(s[i]=='?') q.push(a[i]);
    		if(cnt<0) {
    			if(q.empty()) {
    				puts("-1");return 0;
    			}else sm-=q.top(),q.pop(),cnt+=2;
    		}
    	}
    	if(cnt) puts("-1");
    	else printf("%lld
    ",sm);
    	return 0;
    }
    

      

    题目来源: CodeForces
    基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
     收藏
     关注

    这里有一个关于合法的括号序列的问题。

    如果插入“+”和“1”到一个括号序列,我们能得到一个正确的数学表达式,我们就认为这个括号序列是合法的。例如,序列"(())()", "()"和"(()(()))"是合法的,但是")(", "(()"和"(()))("是不合法的。我们这有一种仅由“(”,“)”和“?”组成的括号序列,你必须将“?”替换成括号,从而得到一个合法的括号序列。

    对于每个“?”,将它替换成“(”和“)”的代价已经给出,在所有可能的变化中,你需要选择最小的代价。

    Input
    第一行是一个非空的偶数长度的字符串,它仅由“(”,“)”和“?”组成。它的长度不大于 50000。接着是m行,m是字符串中“?”的个数。每一行包含两个整数 ai和bi ( 1<=ai,bi<=1000000), ai是将第i个“?”替换成左括号的代价, bi是将第i个“?”替换成右括号的代价。
    Output
    在一行中输出合法的括号序列的最小代价。
    如果没有答案,输出-1。
    Input示例
    (??)
    1 2
    2 8
    Output示例
    4
  • 相关阅读:
    700.二叉搜索树中的搜索
    645.错误的集合
    567.字符串的排列
    560.和为K的子数组
    518.零钱兑换 II
    516.最长回文子序列
    509.斐波那契数
    503.下一个更大元素 II
    496.下一个更大元素 I
    leetcode 1171 Remove Zero Sum Consecutive Nodes from Linked List
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5910800.html
Copyright © 2020-2023  润新知