二分+multiset
今天,胖哥在淘宝上购物。刚开始,胖哥的手上没有任何的优惠券。已知在购物过程中,胖哥将会按顺序遇到 nn 个事件:
1 xx:购买一个价值为 xx 的商品。当发生这种事时,胖哥最多只能使用一张面值小于 xx 的优惠券去减免。若手中没有优惠券,则全额购买。
2 xx:得到一张 xx 元的优惠券。
胖哥想知道,在最优的策略下,完成今天的购物最少要花掉多少钱。
Input
共 n+1n+1 行,第一行包含一个整数 nn,表示事件的个数。
接下来 nn 行,每行两个正整数 typetype xx。若 type=1type=1,表示是事件 1,若 type=2type=2,表示是事件 2。
Output
输出共一行,包含一个整数,表示完成今天的购物最少要花掉多少钱。
Samples
Hint
- 对于 30%的数据,1≤n≤10。
- 对于 60%的数据,1≤n≤1000。
- 对于 100%的数据,1≤n≤100000。
- 对于 100%的数据,1≤x≤100000。
#include<iostream> #include<algorithm> #include<bits/stdc++.h> #include<cstring> using namespace std; typedef long long ll; const ll inf=0x3f3f3f3f; const int maxn=5e6+100; const ll mod=1e9+7; int vis[maxn]; ll n; ll ans=0; ll cnt=0; multiset<int>st; void inint(){ for(int i=1;i<=n;i++){ ll op,x; scanf("%lld%lld",&op,&x); if(op==1){ if(st.empty()){ ans+=x; } else{ multiset <int>::iterator z=st.lower_bound(x); if(z==st.begin()){ ans+=x; } else{ --z; ans+=(x-*z); st.erase(z); } } } else{ st.insert(x); } } } int main(){ cin>>n; inint(); cout<<ans<<endl; }