CF 3D Least Cost Bracket Sequence

題目大意:給一個括號序列,其中有一些位置是問號,問號可以變成左括號或右括號,每個問號變成其中一種符號都有代價。求代價最小的合法括號序列的代價以及序列。

題解:這個問題是有後效性的,因爲後面的決策不取決於前面的某一個階段的狀態,而是與之所有階段的狀態都有關,不能用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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章