JZOJ 3814. 【NOIP2014模拟9.7】天黑黑

22 篇文章 0 订阅
17 篇文章 0 订阅

Description

我走在每天必须面对的分岔路/我怀念过去单纯美好的小幸福/爱总是让人哭/让人觉得不满足/天空很大却看不清楚/好孤独/天黑的时候/我又想起那首歌/突然期待下起安静的雨/原来外婆的道理早就唱给我听/下起雨/也要勇敢前行/我相信/一切都会平息/我现在好想回家去/天黑黑/欲落雨/天黑黑/黑黑
当整个世界陷入黑暗的时候,身为光明之神的Zyh想要用自己的若干个能量源和若干个集流器将这些能量源并成一个最大的能量源,这样他就可以造出最大的灯来照亮整个世界。
具体地来说每个能量源可以直接给出Ei的能量。而每个集流器是由两个接受端口和一个输出端口组成的。集流器有两种:A类和B类。A类是叠加集流器,可以将两个接收端口的能量叠加并输出。B类是取代集流器,可以将两个接受端口的能量较大那个输出。
现在有n-1个集流器,n个能量源。Zyh给出了集流器的连接方式,他想知道怎样放置能量源,能够使最后的输出最大化。

Input

第一行是一个字符串,表示连接的方式。给出的形式是这样的:X,表示一个单独的输出能量源的放置处;AS1S2,其中S1和S2表示两个输出能量,A表示使用叠加集流器将能量并成一个,然后这本身也成为一个新的输出能源;BS1S2也是同理,只不过是使用取代集流器。并且保证A和B的个数为n-1个。X的个数为n个。
第二行是n个正整数,表示这几个能量源。

Output

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

Sample Input

输入1:

BXBXX
8 2 3

输入2:

AXBXX
8 2 3

Sample Output

输出1:

8

输入2:

11

Data Constraint

对于 20% 的数据 n<10
对于 60% 的数据 n<=3000
对于 100% 的数据 n<=200000Ei<=10000

Hint

Hint

Solution

  • 这题实在太坑啦啦啦!!!

  • 先前我打了一个本应 AC 的程序,但由于 OJ 更新把栈限制深度改小了

  • 导致 莫名 错误,调了我几个小时,很来改用人工栈也迷之WA!

  • 好了,回归正题,这题的正解处理很简洁

  • 观察题目,A只会使答案增加,而B却放弃了一些元素

  • 那么贪心地填,将元素排序,选择最终剩余元素个数的那些即可!

  • 使用一个栈,维护可用元素个数,从字符串的后面往前扫,遇到X则压栈,即

    Stack[++top]=1

  • 如果遇到A,则合并两个元素,即:

    Stack[top1]+=stack[top],top

  • 如果是B,就取两个元素的最大值,即:

    if(stack[top]>stack[top1])stack[top1]=stack[top],top;

  • 那么最后 Stack[1] 就是可用元素个数了,依次累加答案即可!

  • 这样时间复杂度就是 O(N)

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=200002;
int n,top,ans;
int a[N],stack[N];
char s[N*2];
inline int read()
{
    int data=0; char ch=0;
    while(ch<'0' || ch>'9') ch=getchar();
    while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();
    return data;
}//读入优化
void put(int x)  
{  
    int num=0; char c[11];
    while(x) c[++num]=(x%10)+48,x/=10;
    while(num) putchar(c[num--]);
}//输出优化
int main()
{
    scanf("%s",s+1);
    for(int i=strlen(s+1);i;i--)
        if(s[i]=='X') stack[++top]=1,n++; else
            if(s[i]=='A') stack[top-1]+=stack[top],top--; else
            {
                if(stack[top]>stack[top-1]) stack[top-1]=stack[top];
                top--;
            }
    for(int i=1;i<=n;i++) a[i]=read();
    sort(a+1,a+1+n);
    for(int i=n-stack[1]+1;i<=n;i++) ans+=a[i];
    put(ans);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值