BZOJ2802/POI 2012 Warehouse Store

Task
有一家专卖一种商品的店,考虑连续的n天。
第i天上午会进货Ai件商品,中午的时候会有顾客需要购买Bi件商品,可以选择满足顾客的要求,或是无视掉他。
如果要满足顾客的需求,就必须要有足够的库存。问最多能够满足多少个顾客的需求。
n<=250,000,0<=Ai<=10^9,0<=Bi<=10^9.

Solution
贪心.
在第i天库存足够时,就满足第i天的顾客的需求;
否则在前i-1个满足了需求的顾客中求出一个需求最大的x,若Bi<x就进行替换.
这里求最值问题可以用堆来实现.

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#define ll long long
#include<queue>
using namespace std;
inline void rd(int &res){
    res=0;char c;
    while(c=getchar(),c<48);
    do res=(res<<1)+(res<<3)+(c^48);
    while(c=getchar(),c>=48);
}
inline void print(int x){
    if(!x)return ;
    print(x/10);
    putchar((x%10)^48);
}
inline void sc(int x){
    if(x<0){x=-x;putchar('-');}
    print(x);
    if(!x)putchar('0');
    putchar('\n');
}
const int M=250005;
struct node{
    int v,id;
    bool operator<(const node &tmp)const{
        return v<tmp.v;
    }
};
priority_queue<node>Q;//大顶堆 
int A[M],n,B[M];
int main(){
    int i,j,k,a,b,ans=0,tot=0;
    scanf("%d",&n);
    ll sum=0;
    for(i=1;i<=n;i++)scanf("%d",&A[i]);
    for(i=1;i<=n;i++)scanf("%d",&B[i]);
    for(i=1;i<=n;i++){
        a=A[i],b=B[i];
        sum+=a;
        if(sum>=b){
            sum-=b;
            ans++;
            Q.push((node){b,i});
        }
        else if(!Q.empty()){
            int x=Q.top().v;
            if(x>b){
                Q.pop();
                Q.push((node){b,i});
                sum+=x-b;
            }
        }
    }
    while(!Q.empty()){
        node x=Q.top();Q.pop();
        A[tot++]=x.id;
    }
    sort(A,A+tot);
    printf("%d\n",ans);
    for(i=0;i<tot;i++)printf("%d ",A[i]);
    puts("");
    return 0;
}

没有更多推荐了,返回首页