二分+multiset

今天,胖哥在淘宝上购物。刚开始,胖哥的手上没有任何的优惠券。已知在购物过程中,胖哥将会按顺序遇到 nn 个事件:
xx:购买一个价值为 xx 的商品。当发生这种事时,胖哥最多只能使用一张面值小于 xx 的优惠券去减免。若手中没有优惠券,则全额购买。
xx:得到一张 xx 元的优惠券。
胖哥想知道,在最优的策略下,完成今天的购物最少要花掉多少钱。

Input

共 n+1n+1 行,第一行包含一个整数 nn,表示事件的个数。
接下来 nn 行,每行两个正整数 typetype xx。若 type=1type=1,表示是事件 1,若 type=2type=2,表示是事件 2。

Output

输出共一行,包含一个整数,表示完成今天的购物最少要花掉多少钱。

Samples

Input Copy
10
2 4
1 6
1 6
2 4
1 1
2 2
2 3
2 3
1 3
1 6
Output
12

Hint

  • 对于 30%的数据,1n10
  • 对于 60%的数据,1n1000
  • 对于 100%的数据,1n100000
  • 对于 100%的数据,1x100000。 
#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;
}
原文地址:https://www.cnblogs.com/lipu123/p/14418799.html