zoukankan      html  css  js  c++  java
  • 超级马里奥

    题目描述
    超级玛丽现在又面临着一系列新的难关,他目前所在的 R 星球包含着 n 个城
    堡,他现在正在城堡 1 中,而他要按照顺序依次通过每个城堡。
    在第 2~n 个城堡中,有的潜伏着一头怪兽,而有的城堡里有一位公主。
    在通关了超级玛丽变态版之后,马里奥现在的水平已经达到了可以秒杀所有
    小怪的境界,在面对怪物的时候,他可以选择是否杀死他,如果干掉他,他可以
    得到一定数量的金币,当然他也可以选择放可怜的怪物一条生路,但是这样他就
    不能得到金币。
    而面对公主,马里奥可能不会太淡定,如果马里奥在遇到某位公主之前杀死
    的怪物数量达到了一个某个给定的值,这位公主就会爱慕这位英雄,而马里奥也
    不会拒绝她的好意,马里奥将会马上终止他的旅程希望与这位公主幸福地生活下
    去。
    但是只有最后一个城堡 n 中的公主才是公主的真身,其余的公主都是最终
    Boss 的假身,但是可怜的 mario 并不知道这一点,如果他被 Boss 引诱到了危险
    的 E 星球后果将不堪设想。只有操控 mario 的你才能帮他完成最终的任务——和
    真正的公主过上幸福的生活。相信聪明的你不仅可以让 mario 完成最终任务,还
    能与此同时最大化 mario 旅程中得到的金币数。
    输入格式
    第一行一个整数 n。
    接下来 n-1 行,分别描述了第 2~n 个城堡的情况。
    若第 i 个城堡中有一只怪兽,那么该行以字母 d 开头,接下来一个正整数 c
    表示杀死这头怪物能够得到的金币。
    若第 i 个城堡中有一位公主,那么该行以字母 p 开头,接下来一个正整数 b
    表示如果 mario 在遇到这位公主之前杀死了不少于 b 只怪物,这位公主就会爱慕
    mario。
    输出格式
    如果马里奥不能完成他的任务,输出一行一个-1,否则输出马里奥的最大收
    益。
    输入样例 1
    6d 10
    d 12
    p2
    d1
    p2
    输出样例 1
    13
    输入样例 2
    6
    d 10
    d 12
    p2
    d1
    p3
    输出样例 2
    -1
    数据规模
    30%的数据,n<=2000。
    另外 30%的数据,max{b}<=50。
    100%的数据,2<=n<=200000,max{c}<=10000,max{b}<=200000,保证城堡
    n 中一定是一位公主。

    处理出一个怪物在哪两个公主中间

    打掉一个怪物,那么之后能打的怪物又少一个

    能打的怪物是后面的最小的公主限制

    那么打掉一个怪,后面的所有公主限制都会减1

    所以贪心,按金币数排序

    然后线段树维护最小值

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 struct ZYYS
     8 {
     9   int val,nxt;
    10 }a[200001];
    11 int c[800001],lazy[800001],n,b[200001],cnt,tot,sum,ans;
    12 bool cmp(ZYYS a,ZYYS b)
    13 {
    14   return a.val>b.val;
    15 }
    16 void pushup(int rt)
    17 {
    18   c[rt]=min(c[rt<<1],c[rt<<1|1]);
    19 }
    20 void build(int rt,int l,int r)
    21 {
    22   if (l==r)
    23     {
    24       c[rt]=b[l];
    25       return;
    26     }
    27   int mid=(l+r)>>1;
    28   build(rt<<1,l,mid);
    29   build(rt<<1|1,mid+1,r);
    30   pushup(rt);
    31 }
    32 void pushdown(int rt)
    33 {
    34   if (lazy[rt])
    35     {
    36       c[rt<<1]+=lazy[rt];
    37       c[rt<<1|1]+=lazy[rt];
    38       lazy[rt<<1]+=lazy[rt];
    39       lazy[rt<<1|1]+=lazy[rt];
    40       lazy[rt]=0;
    41     }
    42 }
    43 int query(int rt,int l,int r,int L,int R)
    44 {
    45   if (l>=L&&r<=R)
    46     {
    47       return c[rt];
    48     }
    49   pushdown(rt);
    50   int mid=(l+r)>>1,s=2e9;
    51   if (L<=mid) s=min(s,query(rt<<1,l,mid,L,R));
    52   if (R>mid) s=min(s,query(rt<<1|1,mid+1,r,L,R));
    53   pushup(rt);
    54   return s;
    55 }
    56 void update(int rt,int l,int r,int L,int R,int d)
    57 {
    58   if (l>=L&&r<=R)
    59     {
    60       c[rt]+=d;
    61       lazy[rt]+=d;
    62       return;
    63     }
    64   int mid=(l+r)>>1;
    65   pushdown(rt);
    66   if (L<=mid) update(rt<<1,l,mid,L,R,d);
    67   if (R>mid) update(rt<<1|1,mid+1,r,L,R,d);
    68   pushup(rt);
    69 }
    70 int main()
    71 {int i,x;
    72   char word[5];
    73   cin>>n;
    74   memset(c,127/2,sizeof(c));
    75   for (i=2;i<=n;i++)
    76     {
    77       scanf("%s",word);
    78       scanf("%d",&x);
    79       if (word[0]=='d') a[++cnt]=(ZYYS){x,tot+1};
    80       else b[++tot]=x;
    81     }
    82   sum=b[tot];b[tot]=200000;
    83   sort(a+1,a+cnt+1,cmp);
    84   build(1,1,tot);
    85   for (i=1;i<=cnt;i++)
    86     {
    87       int t=query(1,1,tot,a[i].nxt,tot);
    88       if (t>1)
    89     {
    90       ans+=a[i].val;
    91       sum--;
    92       update(1,1,tot,a[i].nxt,tot,-1);
    93     }
    94     }
    95   if (sum>0)
    96   cout<<-1;
    97   else cout<<ans;
    98 }
  • 相关阅读:
    扩展欧几里得(exgcd)与同余详解
    卡常模板
    文艺平衡树(区间翻转)
    Motto
    PKUWC2019划水记
    【模板】Splay(洛谷P3391)
    【PKUSC2018】最大前缀和
    【PKUWC2018】随机算法
    【PKUWC2018】Slay the Spire
    【PKUWC2018】Minimax
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8602558.html
Copyright © 2011-2022 走看看