BZOJ2802/POI 2012 Warehouse Store

来源:互联网 发布:淘宝上怎么修改会员名 编辑:程序博客网 时间:2024/06/06 13:08

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;}
0 0
原创粉丝点击