Codeforces 3D Least Cost Bracket Sequence (贪心)

题意: 给出一个包含问号的括号序列,给出每个括号变成 '(' 和 ')'的代价,求将全部问好转换后,序列合法的最小代价。

解法: ‘ 合法序列 ’ 意为序列在从左往右的过程中任意时刻左括号数量不小于右括号,考虑利用该性质:假设现在遍历到位置i,那么在0~i-1的序列都保证合法,若i 为‘)’并且使得0~i序列变为不合法,由于当前不合法状态一定是左比右少1,因此只需要改变0~i的一个')'变成‘(’就可以让0~i变为合法序列,显然我们会选择0~i中转换代价最小的。因此不妨将所有的问号都先置为')',再从左往右维护合法性,每次的选择都是保证当前0~i段合法的最小代价,当i等于len时也成立。用优先队列动态维护当前0~i段')‘的最大b-a。

/* Created Time: Saturday, November 16, 2013 PM07:23:50 CST */
#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
using namespace std;
typedef long long lld;
typedef pair
       
       
         PII; const int N = 55555; char s[N]; int main() { scanf("%s",s+1); lld ss = 0; int cnt = 0; priority_queue 
        
          que; for (int i = 1; s[i]; i ++) { if (s[i]=='(') cnt ++; else if (s[i]==')') cnt --; else { int a,b; scanf("%d%d",&a,&b); ss += b; cnt --; s[i] = ')'; que.push(PII(b-a,i)); } if (cnt<0) { if (que.empty()) break; PII f = que.top(); que.pop(); ss -= f.first; cnt += 2; s[f.second] = '('; } } if (cnt!=0) puts("-1"); else printf("%lld\n%s\n",ss,s+1); return 0; } 
         
       
      
      
     
     
    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值