题意描述

markdown
我走在每天必须面对的分岔路
我怀念过去单纯美好的小幸福
爱总是让人哭
让人觉得不满足
天空很大却看不清楚
好孤独
天黑的时候
我又想起那首歌
突然期待下起安静的雨
原来外婆的道理早就唱给我听
下起雨
也要勇敢前行
我相信
一切都会平息
我现在好想回家去
天黑黑
欲落雨
天黑黑
黑黑

当整个世界陷入黑暗的时候,身为光明之神的Zyh想要用自己的若干个能量源和若干个集流器将这些能量源并成一个最大的能量源,这样他就可以造出最大的灯来照亮整个世界。

具体地来说每个能量源可以直接给出ei的能量。

而每个集流器是由两个接受端口和一个输出端口组成的。集流器有两种:A类和B类。

其中,A类是叠加集流器,可以将两个接收端口的能量叠加并输出。B类是取代集流器,可以将两个接受端口的能量较大那个输出。

现在有n1个集流器,n个能量源。Zyh给出了集流器的连接方式。

他想知道怎样放置能量源,能够使最后的输出最大化。


输入格式

第一行是一个字符串,表示连接的方式。

给出的形式如下:X表示一个单独的输出能量源的放置处;A,S1,S2,其中S1S2表示两个输出能量.

A表示使用叠加集流器将能量并成一个,然后这本身也成为一个新的输出能源;

B也是同理,只不过是使用取代集流器。并且保证AB的个数为n1个。X的个数为n个。

第二行是n个正整数,表示这几个能量源可以提供的能量大小。


输出格式

输出仅有一个数,表示最大的输出能源。


Input & Output ‘s examples

Input ‘s eg 1

markdown
BXBXX
8 2 3

Output ‘s eg 1

markdown
8

Input ‘s eg 2

markdown
AXBXX
8 2 3

Output ‘s eg 2

markdown
11

数据范围与约定

对于20%的数据,保证0<n<10

对于60%的数据,保证0<n<3×103

对于100%的数据,保证0<n<2×105 0<ei<104


分析

一道巧妙的贪心题。

手绘一下两个样例,不难发现,A型集流器对于能量没有损失,而B型集流器会损失掉较小的能量。

因此,我们可以考虑每一次都损失掉能量值最小的能量球。

之后呐?

或许您会将B型能量球的数量记为b,然后将损失掉前b个能量球?

然后您就成功的得到了60分

为什么这样是错的呐?我们考虑举反例。

若在一个B型集流器后接上两个A型集流器,就像下图

反例.png

反例.png

则我们失去的不是一个能量球,而是两个。

对于这个反例,我们直接在输入时使用栈模拟处理即可。

具体实现方法和剩下的细节见代码注释。


Code[Accepted]

cpp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<cctype>
#include<cmath>

#define ll long long
#define I inline
#define N 200001

using namespace std;

ll n , m , a[N];
string s;
ll x;
ll ans = 0;

stack<int > S;

bool cmp(ll a , ll b){
return a > b;
}

int main(){
cin >> s;
for(int i = 0; i < s.length(); i ++){
if(s[i] == 'X'){
x ++; //统计能量球的数量
}
}
for(int i = 1; i <= x; i ++){
scanf("%lld" , &a[i]);
}
sort(a + 1 , a + 1 + x , cmp); //对能量球进行降序排序
for(int i = s.length() - 1; i >= 0; i --){ //倒序扫描,便于模拟
if(s[i] == 'X'){ //如果当前位置可以放能量球,则放入
S.push(1);
}
else if(s[i] == 'A'){ //如果是A型集流器,则将后边的两个位置加起来
int top1 = S.top();
S.pop();
int top2 = S.top();
S.pop();
S.push(top1 + top2);
}
else{ //如果是B型,则删掉较小的那一个。
int top1 = S.top();
S.pop();
int top2 = S.top();
S.pop();
if(top1 > top2){
S.push(top1);
}
else{
S.push(top2);
}
}
} //最后的栈顶则是可以取到的能量球数。
for(int i = 1; i <= S.top(); i ++){
ans += a[i];
}
printf("%lld" , ans);
return 0;
}


THE END