CF 3D Least Cost Bracket Sequence

6 篇文章 0 订阅

题目大意:给一个括号序列,其中有一些位置是问号,问号可以变成左括号或右括号,每个问号变成其中一种符号都有代价。求代价最小的合法括号序列的代价以及序列。

题解:这个问题是有后效性的,因为后面的决策不取决于前面的某一个阶段的状态,而是与之所有阶段的状态都有关,不能用dp来解。正解是贪心,先假设所有的问号都是右括号,如果某个位置不合法了,检查前面是否有问号,如果有的话找一个代价最小的进行纠正,否则一定无法构成正确的序列。

#include <bits/stdc++.h>

using namespace std;

const int maxn = 50100;

struct node{
    int idx,a,b;
    node(int i,int x,int y):idx(i),a(x),b(y){}
    node(){}
    bool operator<(const node &x)const {
        return a-b>x.a-x.b;
    }
};


priority_queue<node> Q;
typedef long long ll;
int a[maxn],b[maxn];
int id[maxn];
char str[maxn];


int main(){
    scanf("%s",str);
    int len = strlen(str);
    int n = 0;
    for(int i = 0;i < len;i++)
        if(str[i] == '?'){
            str[i] = ')';
            id[n++] = i;
        }
    ll ans = 0;
    int cnt = 0;
    bool flag = true;
    for(int i = 0;i < n;i++) scanf("%d%d",&a[i],&b[i]),ans +=b[i];
    for(int i = 0,j = 0;i < len;i++){
        if(i == id[j]){
            Q.push(node(i,a[j],b[j]));
            j++;
        }
        if(str[i] == '(') cnt++;
        if(str[i] == ')') cnt--;
        if(cnt < 0){
            if(!Q.empty()){
                node tmp = Q.top();
                Q.pop();
                ans += tmp.a-tmp.b;
                cnt += 2;
                str[tmp.idx] = '(';
            }
            else{
                flag = false;
                break;
            }
        }
    }
    if(cnt>0) flag = false;
    if(!flag){
        printf("-1\n");
        return 0;
    }
    printf("%I64d\n",ans);
    printf("%s\n",str);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值