【51Nod1476】括号序列的最小代价
2017-09-02 17:17
477 查看
这里有一个关于合法的括号序列的问题。
如果插入“+”和“1”到一个括号序列,我们能得到一个正确的数学表达式,我们就认为这个括号序列是合法的。例如,序列”(())()”, “()”和”(()(()))”是合法的,但是”)(“, “(()”和”(()))(“是不合法的。我们这有一种仅由“(”,“)”和“?”组成的括号序列,你必须将“?”替换成括号,从而得到一个合法的括号序列。
对于每个“?”,将它替换成“(”和“)”的代价已经给出,在所有可能的变化中,你需要选择最小的代价。
Input
第一行是一个非空的偶数长度的字符串,它仅由“(”,“)”和“?”组成。它的长度不大于 50000。接着是m行,m是字符串中“?”的个数。每一行包含两个整数 ai和bi ( 1<=ai,bi<=1000000), ai是将第i个“?”替换成左括号的代价, bi是将第i个“?”替换成右括号的代价。
Output
在一行中输出合法的括号序列的最小代价。
如果没有答案,输出-1。
Input示例
(??)
1 2
2 8
Output示例
4
题解
先把所有问号填成),从左往右扫,弄个计数器tot,判断当前左括号多还是右括号多,当右括号多时贪心修改之前代价最小的括号,用堆维护。
代码
如果插入“+”和“1”到一个括号序列,我们能得到一个正确的数学表达式,我们就认为这个括号序列是合法的。例如,序列”(())()”, “()”和”(()(()))”是合法的,但是”)(“, “(()”和”(()))(“是不合法的。我们这有一种仅由“(”,“)”和“?”组成的括号序列,你必须将“?”替换成括号,从而得到一个合法的括号序列。
对于每个“?”,将它替换成“(”和“)”的代价已经给出,在所有可能的变化中,你需要选择最小的代价。
Input
第一行是一个非空的偶数长度的字符串,它仅由“(”,“)”和“?”组成。它的长度不大于 50000。接着是m行,m是字符串中“?”的个数。每一行包含两个整数 ai和bi ( 1<=ai,bi<=1000000), ai是将第i个“?”替换成左括号的代价, bi是将第i个“?”替换成右括号的代价。
Output
在一行中输出合法的括号序列的最小代价。
如果没有答案,输出-1。
Input示例
(??)
1 2
2 8
Output示例
4
题解
先把所有问号填成),从左往右扫,弄个计数器tot,判断当前左括号多还是右括号多,当右括号多时贪心修改之前代价最小的括号,用堆维护。
代码
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<set> #include<ctime> #include<vector> #include<cmath> #include<algorithm> #include<map> #include<queue> #define mod 1000000007 #define ll long long #define inf 1e9 using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } priority_queue<int,vector<int>,greater<int> >q; int len,a[50005],b[50005]; ll ans=0LL; char s[50005]; int main() { scanf("%s",s); len=strlen(s); for (int i=0;i<len;i++) if (s[i]=='?') { scanf("%d%d",&a[i],&b[i]); ans+=b[i]; } int tot=0; for (int i=0;i<len;i++) { if (s[i]=='(') tot++; else tot--; if (s[i]=='?') q.push(a[i]-b[i]); if (tot<0) { if (q.empty()) return printf("-1"),0; ans+=q.top( ee86 );q.pop();tot+=2; } } if (tot>0) return printf("-1"),0; printf("%lld",ans); return 0; }
相关文章推荐
- 优先队列+括号配对 51Nod1476 括号序列的最小代价
- 51nod 1476 括号序列的最小代价【贪心】【堆】
- 51nod 1476 括号序列的最小代价
- 51nod 1476 括号序列的最小代价(贪心)
- 51Nod-1476-括号序列的最小代价
- [贪心] 51Nod1476 括号序列的最小代价
- 括号序列的最小代价
- 51node1476 括号序列的最小代价(贪心)
- 【贪心】51Nod 1476 括号序列的最小代价
- 有向树与树的括号序列最小表示法
- #牛客#代码实现:最小编辑代价、最长增长子序列、汉诺塔进阶、单链表相交
- 有向树与树的括号序列最小表示法
- 2017-5-14 湘潭市赛 Parentheses 转化思想+贪心 使括号序列合法的最小花费。满足前面左括号的数量>=有括号的数量。
- Codeforces Round #371 (Div. 2) E 【DP+离散化 LIS 】用最小代价把序列变成严格递增序列
- 【codeforces 13 C】【DP + 离散化 + 贪心+滚动数组 】C. Sequence【用最小代价把序列变成非严格递增序列】
- Codeforces3D#51nod1476 括号匹配的最小代价
- 有向树与树的括号序列最小表示法
- LintCode:有效的括号序列
- vijos 1448 校园外的数 树状数组 括号序列
- 求一个序列中最小的自左到右最小的分组数