烤鸡翅

【题目描述】

在焦作太行路上,有一家烤鸡翅的生意火爆。因为好吃,所以卖的特别好。排队的人就特别多,经常有很多人买不到鸡翅。

鸡翅会在每分钟烤出Xi个,每分钟也只会卖给一个客人,第i个客人需要买Yi个。因为生意火爆,老板可以选择在这分钟不卖给这个客人鸡翅,或者卖给这个顾客他需要的鸡翅, 如果现在剩余的鸡翅不够,那就肯定不能卖给这个客人。无论这个客人能否买到鸡翅,他必须离开队伍。

现在给定N分钟,且已经知道每分钟烤出的鸡翅个数Xi,也知道每个客人需要鸡翅的Yi个数,现在老板想知道,如何合理安排卖给与拒绝,最多可以满足多少人

【输入格式】

第一行一个正整数N,表示有N分钟的时间卖鸡翅

第二行N个用空格隔开的整数 X1,X2……Xn,Xi表示第i分钟会有Xi个鸡翅烤出

第三行N个用空格隔开的整数Y1,Y2……Yn,Yi表示第i分钟的顾客需要Yi个鸡翅

【输出格式】

一个整数,表示最多可以满足买到鸡翅的人数。

【样例输入】

6

2 2 1 2 1 0

1 2 2 3 4 4

【样例输出】

3

【提示】

【数据范围】

  50%  数据保证 N<=1000

  100%  1<=N<=250000   Xi,Yi都在[0,10^9]范围内

题解

       喜闻乐见的贪心。用了一种非常新奇(据说也很常用)的反悔思路。因为是要卖给尽量多的客人,所以对于每一个客人,如果现有的鸡翅够他买就直接卖给他,jg++;如果没有足够的鸡翅且之前有人买走了比他需要的还多的鸡翅,卖给他一定比卖给那个人更优(不仅答案大小不变,剩下的鸡翅还变多了),于是果断反悔把卖出的鸡翅拿回来卖给当前客人。这样维护一个优先队列记录卖出的鸡翅,简单地贪心就可以解决问题。这道水题却错了无数遍,开始是因为思路整个就是混乱的,后来因为优先队列不记得判空,最后有一个点炸掉int必须改成long long。队列判不判空,在做这个专题的时候是绝对不会忘的,现在却完全没有这种意识。通过做题把原来的知识和坑都捡起来,是联赛之前很重要的一个任务吧。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int sj=250010;
int n,jg,x[sj],y[sj];
long long cz;
priority_queue<int, vector<int>, less<int> > miti;
int main()
{
    //freopen("t.txt","r",stdin);
    freopen("wing.in","r",stdin);
    freopen("wing.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
       scanf("%d",&x[i]);
    for(int i=1;i<=n;i++)
       scanf("%d",&y[i]);
    for(int i=1;i<=n;i++)
    {
       cz+=x[i];
       if(cz>=y[i])
       {
          cz-=y[i];
          jg++;
          miti.push(y[i]);
       }
       else if(!miti.empty()&&miti.top()>y[i])
       {
          cz+=miti.top()-y[i];
          miti.pop();
          miti.push(y[i]);
       }
    }
    printf("%d",jg);
    //while(1);
    return 0;
}
原文地址:https://www.cnblogs.com/moyiii-/p/7241530.html