1. 程式人生 > >超級馬裏奧

超級馬裏奧

blog memset 情況 HA 選擇 與此同時 col 順序 排序

題目描述
超級瑪麗現在又面臨著一系列新的難關,他目前所在的 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 }

超級馬裏奧