BZOJ1828: [Usaco2010 Mar]balloc 农场分配
n<=100000个房容量Ai,m<=100000头牛分别要占Li~Ri的房,求能同时满足的牛最多有多少。
先把这些各种各样要求的牛排个序观察一下,可以发现,如果若干头牛的Li是一样的,而Li处的容量不允许它们同时放,这时就要舍弃Ri大的那几头,因为价值相同,舍弃谁都不会影响当前的答案,但Ri大的对后面的牛可能产生阻碍。
这里所说的Li一样,其实可以更广泛地说,如果当前考虑的房中,前面的房满足要求,而这个房加入新牛后爆炸了,就应该把现在在房里的所有的牛中Ri大的那几头舍弃。
我们需要一个支持插入删除和查最大的结构——priority_queue!
ps:如果给每头牛加上权值,如何求权最大??
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<queue> 6 //#include<iostream> 7 using namespace std; 8 9 int n,m; 10 #define maxn 100011 11 int a[maxn],e[maxn]; 12 struct segment 13 { 14 int l,r; 15 bool operator < (const segment &b) const {return l<b.l;} 16 }p[maxn]; 17 priority_queue<int> que; 18 int x,y; 19 int main() 20 { 21 scanf("%d%d",&n,&m); 22 for (int i=1;i<=n;i++) scanf("%d",&a[i]); 23 memset(e,0,sizeof(e)); 24 for (int i=1;i<=m;i++) 25 { 26 scanf("%d%d",&x,&y); 27 p[i].l=x;p[i].r=y; 28 e[x]++;e[y+1]--; 29 } 30 sort(p+1,p+1+m); 31 int now=0,j=1,ans=m; 32 for (int i=1;i<=n;i++) 33 { 34 now+=e[i]; 35 while (j<=m && p[j].l==i) que.push(p[j++].r); 36 for (;now>a[i];now--) 37 { 38 e[que.top()+1]++; 39 que.pop(); 40 ans--; 41 } 42 } 43 printf("%d\n",ans); 44 return 0; 45 }