Design and Analysis of Algorithms 4.5 Hong Nima and mysterious envelope

★ Title Description

Only one of "o", "X" and a character string consisting of "*", the "*" replaced by "o" requires a cost, the cost of replacing the need b "X."

A string legitimate need to meet the following two conditions:

The number "o" of all prefix string must be not less than 1. The number of "x";

2. The number of the string "o" must be equal to the number of "x";

Hong Nima want to know all the "*" replace "o" or "x" so that the string is a legal minimum cost how much?

If no solution outputs -1.

★ input format

The first line a string S, the string represented;

Next m lines of two positive integers ai, bi, represents replaced by "o", the cost required for "x";

For 60% of the data string length is not greater than 1000;

To 100% of the data string length is not greater than 100000,0 <= ai, bi <= 108.

★ output format

If solutions, it outputs a positive integer representing the minimum cost;

If there is no solution, the output of -1.

★ sample input

o**x
1 2
3 5

★ Sample Output

5

★ Tips

no

★ reference code

/*
https://blog.csdn.net/f_zyj/article/details/74158391

优先队列优化的贪心问题。

优先队列 + 贪心
1.第一次遍历字符串,把“*”全部用“ x ”替换。在替换过程中记录一下所花代价 sum ,并把 a-b 值加入到一个队列;
2.开始第二次遍历字符串,此时记录 cnt,每当 cnt<0时,表明需要往前面字符串o字符不足,就可以选择队列中的最小的位置替换,等于“*”-> “x”-> “o”,此时 cnt+2、sum+(a-b)
*/ 
#include<bits/stdc++.h>
using namespace std;
int n;
char S[100005];
int A[100005]={0};
int B[100005]={0};
long long sum = 0; //记录代价 
int cnt = 0; //记录o和x的个数差 
priority_queue<int> pqi;


long long fun(){
    for(int i=0; i<n; ++i){
        if(S[i] == 'o') ++cnt;
        else if(S[i]=='x' || S[i]=='*') --cnt;

        if(S[i]=='*') pqi.push(B[i]-A[i]);    //替换时,a[i] - b[i],考虑优先出来大的,故取反

        if(cnt < 0) {
            if(pqi.empty()) return -1;
            sum -= pqi.top();
            pqi.pop();
            cnt += 2;
        }
    }
    if (cnt != 0) return -1;
    return sum; 
}


int main(){
    scanf("%s", S);
    n = (int)strlen(S);

    for(int i=0; i<n; ++i){
        if(S[i]=='*'){
            scanf("%d%d",&A[i],&B[i]);
            sum += B[i];
        }
    }

    printf("%lld\n", fun());

    return 0;
}

Guess you like

Origin www.cnblogs.com/yejifeng/p/12078883.html