Although Farmer John has no problems walking around the fair to collect prizes or see the shows, his cows are not in such good shape; a full day of walking around the fair leaves them exhausted. To help them enjoy the fair, FJ has arranged for a shuttle truck to take the cows from place to place in the fairgrounds.
FJ couldn't afford a really great shuttle, so the shuttle he rented traverses its route only once (!) and makes N (1 <= N <= 20,000) stops (conveniently numbered 1..N) along its path. A total of K (1 <= K <= 50,000) groups of cows conveniently numbered 1..K wish to use the shuttle, each of the M_i (1 <= M_i <= N) cows in group i wanting to ride from one stop S_i (1 <= S_i < E_i) to another stop E_i (S_i < E_i <= N) farther along the route.
The shuttle might not be able to pick up an entire group of cows (since it has limited capacity) but can pick up partial groups as appropriate.
Given the capacity C (1 <= C <= 100) of the shuttle truck and the descriptions of the groups of cows that want to visit various sites at the fair, determine the maximum number of cows that can ride the shuttle during the fair.
逛逛集市,兑兑奖品,看看节目对农夫约翰来说不算什么,可是他的奶牛们非常缺乏锻炼——如果要逛完一整天的集市,他们一定会筋疲力尽的。所以为了让奶牛们也能愉快地逛集市,约翰准备让奶牛们在集市上以车代步。但是,约翰木有钱,他租来的班车只能在集市上沿直线跑一次,而且只能停靠N(1 ≤N≤20000)个地点(所有地点都以1到N之间的一个数字来表示)。现在奶牛们分成K(1≤K≤50000)个小组,第i 组有Mi(1 ≤Mi≤N)头奶牛,他们希望从Si跑到Ti(1 ≤Si<Ti≤N)。
由于班车容量有限,可能载不下所有想乘车的奶牛们,此时也允许小里的一部分奶牛分开乘坐班车。约翰经过调查得知班车的容量是C(1≤C≤100),请你帮助约翰计划一个尽可能满足更多奶牛愿望的方案。
输入输出格式
【输入】
第一行:包括三个整数:K,N和C,彼此用空格隔开。
第二行到K+1行:在第i+1行,将会告诉你第i组奶牛的信息:Si,Ei和Mi,彼
此用空格隔开。
【输出】
第一行:可以坐班车的奶牛的最大头数。
输入输出样例
说明
班车可以把2头奶牛从1送到5,3头奶牛从5送到8,2头奶牛从8送到14,1头
奶牛从9送到12,1头奶牛从13送到14,1头奶牛从14送到15。
--------------------------------------------------------------------------------------------------------------------------
本来想用这道题来练一下线段树的,结果反而发现了贪心这个大坑然后顺势补了一下????
never mind....那就两个都写一下吧
首先强烈安利一个blog!!点击这里 直到看了这个我才终于搞懂了贪心的思路。
我们要枚举的不是整个行程1~n怎样填满,而是一次一次的(从1~k)将每组牛往空余的座位塞。
对于每组奶牛,我们要选择上一次下车位置最接近下一次起点的座位接上去
用h[c]记录每个座位最后被占用的时间节点。
读入之后k组牛先按照 最早结束为第一关键字、最早开始为第二关键字排序,然后开始贪心枚举
每一次从h[c]中取出结束时间最早的座位 如果在当前枚举的i组开始前就已经空了,就可以坐下
坐下一只牛,ans++
具体贪心证明请看上面的链接
代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define N 50010 7 using namespace std; 8 struct node 9 { 10 int m,s,t; 11 }e[N]; 12 bool cmp(node a,node b) 13 { 14 if(a.t!=b.t) 15 return a.t<b.t; 16 return a.s<b.s; 17 } 18 bool cmmp(int a,int b) 19 { 20 return a>b; 21 } 22 int n,k,c,ans; 23 int h[150];//第i处被占用结束的时间 24 int main() 25 { 26 scanf("%d%d%d",&k,&n,&c); 27 for(int i=1;i<=k;i++) 28 scanf("%d%d%d",&e[i].s,&e[i].t,&e[i].m); 29 sort(e+1,e+k+1,cmp); 30 for(int i=1;i<=k;i++) 31 { 32 sort(h+1,h+c+1,cmmp); 33 for(int j=1;j<=c&&e[i].m;j++) 34 { 35 if(h[j]<=e[i].s) 36 { 37 ans++; 38 h[j]=e[i].t; 39 e[i].m--; 40 } 41 } 42 } 43 printf("%d",ans); 44 return 0; 45 }
那么线段树又用在哪里呢?
如果数据水,我们可以在每一选择h[c]的时候排一次序,但如果数据认真,这个过程就可以用线段树维护。
这是代码:
upd:
哭了
我又看了一个小时也没反应过来线段树怎么加
太菜了QAQ
upd2:
我终于看懂了!!!!
原来加入线段树之后,整个过程就回到了我最早的那种思路啦!!!!
就是维护的区间是1~n的整条路的长度,每组牛看作为一个子区间
用子区间覆盖总区间,然后求的是 在重叠部分厚度(即重叠区间数)不超过c的情况下能取的最大子区间个数(当然每个区间有重复m_i次)
然后就变成区间查询最大值和区间修改了
每次查最大值有没有超过c,并和本组的牛数做比较,累计答案,区间内的牛数++;
好啦代码就明天再更了ovo
(太迷幻了 三天以前的思路就是正解但但是不知道怎么处理并且还一心想要先写贪心 233333333)