P3088 [USACO13NOV]挤奶牛Crowded Cows(单调队列)


题目描述

Farmer John has N cows that need to be milked (1 <= N <= 10,000), each of which takes only one unit of time to milk.

Being impatient animals, some cows will refuse to be milked if Farmer John waits too long to milk them. More specifically, cow i produces g_i gallons of milk (1 <= g_i <= 1000), but only if she is milked before a deadline at time d_i (1 <= d_i <= 10,000). Time starts at t=0, so at most x total cows can be milked prior to a deadline at time t=x.

Please help Farmer John determine the maximum amount of milk that he can obtain if he milks the cows optimally.

FJ有N(1 <= N <= 10,000)头牛要挤牛奶,每头牛需要花费1单位时间。

奶牛很厌烦等待,奶牛i在它的截止时间d_i (1 <= d_i <= 10,000)前挤g(1 <= g_i <= 1000)的奶,否则将不能挤奶。时间t开始时为0,即在时间t=x时,最多可以挤x头奶牛。

请计算FJ的最大挤奶量。

输入输出格式

输入格式:

* Line 1: The value of N.

* Lines 2..1+N: Line i+1 contains the integers g_i and d_i.

输出格式:

* Line 1: The maximum number of gallons of milk Farmer John can obtain.

输入输出样例

输入样例#1:
复制

4
10 3
7 5
8 1
2 1

输出样例#1: 复制

25

说明

There are 4 cows. The first produces 10 gallons of milk if milked by time 3, and so on.

Farmer John milks cow 3 first, giving up on cow 4 since she cannot be milked by her deadline due to the conflict with cow 3. Farmer John then milks cows 1 and 2.




楼下STL的nlogn做法也很巧妙啊

这里说一下O(n)的单调队列做法

首先每个元素肯定要按照位置排序,然后依次进队,判断如果队尾的数大小小于要进队的数,那就把队尾弹出,直到队尾的数大于等于要进队的数

这是为了维护单调性

然后再判断如果队头的数位置的差值大于d,出队,直到差值小于d,此时队头的数为单调队列内的合法最大值

因此只要将要进队的数与目前的队头元素比较即可

这样维护了前面的,后面的反一下就好了

时间复杂度:因为每个元素最多进队出队一次,所以是O(n)的

单调队列有单向性,这个题对两边都有要求,所以要正反向跑两次。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct ppap{
 4     int x,y;
 5 }a[100001];
 6 ppap qq[100001];
 7 bool q[100001],h[100001];
 8 inline bool cmp(ppap a,ppap b){return a.x<b.x;}
 9 int main()
10 {
11     int n,d;scanf("%d%d",&n,&d);
12     for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
13     sort(a+1,a+n+1,cmp);
14     int l=1,r=0;
15     for(int i=1;i<=n;i++){
16         while(l<=r&&qq[r].y<a[i].y)r--;
17         qq[++r]=a[i];
18         while(l<=r&&qq[l].x<a[i].x-d)l++;
19         if(qq[l].y>=a[i].y*2)q[i]=1;
20     }
21     memset(qq,0,sizeof qq);l=1;r=0;
22     for(int i=n;i;i--){
23         while(l<=r&&qq[r].y<a[i].y)r--;
24         qq[++r]=a[i];
25         while(l<=r&&qq[l].x>a[i].x+d)l++;
26         if(qq[l].y>=a[i].y*2)h[i]=1;
27     }
28     int ans=0;
29     for(int i=1;i<=n;i++)if(q[i]&&h[i])ans++;
30     printf("%d",ans);
31     return 0;
32 }

原文地址:https://www.cnblogs.com/zhangbuang/p/10284364.html

时间: 2024-11-05 09:36:23

P3088 [USACO13NOV]挤奶牛Crowded Cows(单调队列)的相关文章

BZOJ 3314: [Usaco2013 Nov]Crowded Cows( 单调队列 )

从左到右扫一遍, 维护一个单调不递减队列. 然后再从右往左重复一遍然后就可以统计答案了. ---------------------------------------------------------------------------- #include<bits/stdc++.h> #define rep(i, n) for(int i = 0; i < n; ++i) #define clr(x, c) memset(x, c, sizeof(x)) #define forea

单调队列单调栈

单调队列单调栈 Tags:数据结构 更好阅读体验:https://www.zybuluo.com/xzyxzy/note/1041449 一.概述 单调队列单调栈是很基础的数据结构,常用来优化一些东西比如说优化DP 那么大概意思就是在栈或队列中按照某关键字单调维护信息,从而实现一些功能 其实很久之前接触过单调队列和单调栈,但一直没有刷题,趁这两天被LCT弄晕的时候复习下这些 先看题 二.题单 普及- [x] P1886 滑动窗口 https://www.luogu.org/problemnew/

【BZOJ1915】[Usaco2010 Open]奶牛的跳格子游戏 DP+单调队列

[BZOJ1915][Usaco2010 Open]奶牛的跳格子游戏 Description 奶牛们正在回味童年,玩一个类似跳格子的游戏,在这个游戏里,奶牛们在草地上画了一行N个格子,(3 <=N <= 250,000),编号为1..N.就像任何一个好游戏一样,这样的跳格子游戏也有奖励!第i个格子标有一个数字V_i(-2,000,000,000 <=V_i <= 2,000,000,000)表示这个格子的钱.奶牛们想看看最后谁能得到最多的钱.规则很简单: * 每个奶牛从0号格子出发

小结:单调栈 &amp; 单调队列

概要: 对于维护信息具有单调性的性质或者问题可以转化为具有单调性质的模型的题,我们可以考虑用单调栈或单调队列. 技巧及注意: 技巧很多,只要能将问题转化为单调性问题,就好解决了. 当维护固定长度的单调区间,我们考虑用单调队列,如[BZOJ]3314: [Usaco2013 Nov]Crowded Cows(单调队列) 单调栈维护长度时要进行及时更新,例如:[BZOJ]3039: 玉蟾宫(DP/单调栈) 假设完美状态后再进行减法原理,例如:[BZOJ]1628 && 1683: [Usaco

单调队列以及单调队列优化DP

单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2.优化DP 例题引入: https://www.luogu.org/problemnew/show/P1440 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. 例题解答: 首先看到题目可以很快想到O(

BZOJ3314: [Usaco2013 Nov]Crowded Cows

3314: [Usaco2013 Nov]Crowded Cows Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 86  Solved: 61[Submit][Status] Description Farmer John's N cows (1 <= N <= 50,000) are grazing along a one-dimensional fence. Cow i is standing at location x(i) and has

单调队列优化动态规划

先来看这道题: USACO 2011 Open Gold Mowing the Lawn 修剪草坪 After winning the annual town competition for best lawn a year ago, Farmer John has grown lazy; he has not mowed the lawn since then and thus his lawn has become unruly. However, the competition is on

[ACM] poj 2823 Sliding Window (单调队列)

高一时,学校组织去韶山游玩,我没去,这次趁着五一,总算去了我心心念念的韶山.其实我知道所有的景点都是差不多的,可是因为电视剧<恰同学少年>,让我对毛泽东有了进一层的了解,所以,我一直都想去看看. 有两个同学一男一女是我理想的旅友,可是女生不想去,而男士回家了.所以,我独自一人去了. 准备工作:一小包饼干,一小包山楂片,两个苹果,一瓶水,帽子(防晒),墨镜(装酷) 早晨5:30起床了,洗漱完毕,吃完早餐,赶到公交车站牌那里,才6点过几分.公交车6:31才到,等了近半个小时(公交车上明明说是6:0

bzoj 3126: [Usaco2013 Open]Photo——单调队列优化dp

Description 给你一个n长度的数轴和m个区间,每个区间里有且仅有一个点,问能有多少个点 Input * Line 1: Two integers N and M. * Lines 2..M+1: Line i+1 contains a_i and b_i. Output * Line 1: The maximum possible number of spotted cows on FJ's farm, or -1 if there is no possible solution. S