【贪心】bzoj1577: [Usaco2009 Feb]庙会捷运Fair Shuttle
一类经典的线段贪心
Description
公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N。K(1<=K<=50000)群奶牛希望搭乘这辆公交车。第i群牛一共有Mi(1<=Mi<=N)只.
他们希望从Si到Ei去。
公交车只能座C(1<=C<=100)只奶牛。而且不走重复路线,请计算这辆车最多能满足多少奶牛听要求。
注意:对于每一群奶牛,可以部分满足,也可以全部满足,也可以全部不满足。
Input
第1行: 三个整数: K,N,C。 由空格隔开。
第2..K+1行:第i+1行,告诉你第i组奶牛的信息: S_i, E_i and M_i。由空格隔开。
Output
一行:可以在庙会乘坐捷运的牛的最大头数
HINT
捷运可以把2头奶牛从展台1送到展台5,3头奶牛从展台5到展台8, 2头奶牛从展台8 到展台14,1头奶牛从展台9送到展台12,一头奶牛从展台13送到展台14, 一头奶牛从 14送到15。
题目分析
这种“线段贪心”,最经典的莫过于容量为1的情况。
容量为1时,做法就是按照右端点排序,$O(n)$扫一遍选取不冲突的线段。这个贪心之所以不需要“反悔”,是因为价值和容量一一对应:每一时刻不论选哪一条线段,获得价值都是1.从这个角度上来说,所有线段是无差别的。
想法自然但不正确的贪心1
从容量为1的情况会想到:既然答案可以看做是c次互不影响的“容量为1”路径,那就做c次$O(n)$的贪心嘛。
上图中,最优决策的确可以看做是c次互不影响的决策。但是当我们去选取线段时,会发现按照r端点排序的贪心策略在分配c组互不影响的决策上失效了。
依然按照r排序的正确贪心2
这里采用一种非形式化的语言描述这种贪心策略的正确性:
对于总的安排来说,目标是让每一时刻容量都不要空闲;对于细的策略来说,因为这里线段可以拆开,所以目标是让选取的线段越少冲突越好。
那么先按照r排序。排序后,当然是越靠前的线段越“好”。这里的“好”指的是,这条线段既把之前的容量利用起来;又对后面的线段产生较小的影响。
实在不行可以假设这个结论就是对的……
那么我是用永久标记线段树来维护这个贪心过程。
#include<bits/stdc++.h>
const int maxn = ; struct node
{
int l,r,v;
bool operator < (node a) const
{
return r < a.r;
}
}edges[maxn];
int k,n,c,ans;
int f[maxn<<],add[maxn<<]; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
int query(int rt, int L, int R, int l, int r, int hd)
{
if (L <= l&&r <= R){
return f[rt]+hd;
}
int mid = (l+r)>>, ans = ;
if (L <= mid) ans = std::max(query(rt<<, L, R, l, mid, hd+add[rt]), ans);
if (R > mid) ans = std::max(query(rt<<|, L, R, mid+, r, hd+add[rt]), ans);
return ans;
}
void pushup(int rt)
{
f[rt] = std::max(f[rt<<], f[rt<<|])+add[rt];
}
void adds(int rt, int L, int R, int l, int r, int c)
{
if (L <= l&&r <= R){
f[rt] += c, add[rt] += c;
return;
}
int mid = (l+r)>>;
if (L <= mid) adds(rt<<, L, R, l, mid, c);
if (R > mid) adds(rt<<|, L, R, mid+, r, c);
pushup(rt);
}
int main()
{
k = read(), n = read(), c = read();
for (int i=; i<=k; i++)
edges[i].l = read(), edges[i].r = read(), edges[i].v = read();
std::sort(edges+, edges+k+);
for (int i=; i<=k; i++)
{
int delta = std::min(c-query(, edges[i].l, edges[i].r, , n, ), edges[i].v);
ans += delta;
if (delta)
adds(, edges[i].l, edges[i].r-, , n, delta);
}
printf("%d\n",ans);
return ;
}
END
【贪心】bzoj1577: [Usaco2009 Feb]庙会捷运Fair Shuttle的更多相关文章
- bzoj1577 [Usaco2009 Feb]庙会捷运Fair Shuttle
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1577 [题解] 我们把每坨奶牛按s排个序. 对于每坨奶牛,如果车上有空位置就塞. 否则,看下 ...
- [bzoj1577][Usaco2009 Feb]庙会捷运Fair Shuttle_贪心_线段树
庙会捷运 Fair Shuttle bzoj-1577 Usaco-2009 Feb 题目大意:有一辆公交车从1走到n.有m群奶牛从$S_i$到$E_i$,第i群奶牛有$W_i$只.车有一个容量c.问 ...
- bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle——小根堆+大根堆+贪心
Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1& ...
- BZOJ 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle 线段树 + 贪心
escription 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1&l ...
- [Usaco2009 Feb]庙会捷运Fair Shuttle
Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1& ...
- bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle【贪心+线段树】
按结束时间排序,然后开个线段树,按照排序后的牛群贪心的选 贪心的依据是选哪头牛都是选,不如给后面的多省一点空间 #include<iostream> #include<cstdio& ...
- 【BZOJ】1577: [Usaco2009 Feb]庙会捷运Fair Shuttle
[题意]公车从1开到n,有k群牛想从一个点到达另一个点,公车最多乘坐c个人,牛群可以拆散,问最多载多少牛到达目的地. [算法]贪心+堆 [题解]线段和点的贪心,一般有按左端点排序和按右端点排序两种方法 ...
- <USACO09FEB>庙会捷运Fair Shuttleの思路
一个没有被我成功证明的 贪心 但是 ac了的 别人排序都是排终点.但我的排终点错了emm排起点才对qvq 有没有人友情看看怎么证(没有 #include<cstdio> #include& ...
- 洛谷 P1607 [USACO09FEB]庙会班车Fair Shuttle 解题报告
P1607 [USACO09FEB]庙会班车Fair Shuttle 题目描述 Although Farmer John has no problems walking around the fair ...
随机推荐
- php高并发之opcache
今天工作的时候接触到客户的一台服务器,业务逻辑比较简单 .估算pv在120w左右吧,用的是阿里云2c4g的服务器.一大早就开始卡顿了,登陆服务器后查看负载到了八九十. 之后就想办法调整一下吧.突然想起 ...
- react native 使用iconfont
安卓的配置: 1.在android/app/src/assets/fonts文件夹下复制从iconfont下载的 (下载后的icon名称可以在下载来的文件中的html文件中) 2.在android ...
- js中 前台日期时间使用方法总结
(1)JQuery EasyUI 1.4.2 版本中的 DateTimeBox(时间日期输入框) 参考本地帮助文档. (2)jquery.datetimepicker 单独使用的包 只 ...
- Python中输出字体的颜色设置
1.实现过程 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关.控制字符颜色的转义序列是以ESC开头,即用\033来完成 2.书写过程 开头部分: \033[显示方式;前 ...
- awk单引号处理
awk中使用单引号,常规字符串,'\''即可,但如果像下面在$4变量用单引号,则还需要加上双引号才行. cat 2.txt | awk '{ print $1, $2, $3, "'\''& ...
- hashMap的具体实现
HashMap是Java中的一个重要的数据结构! 与HashMap更重要的一个数据结构是HashTable,其中最重要的区别是HashTable传说中是线程安全的(之所以说他是传说是因为我并没有去理解 ...
- setTimeout() 实现程序每隔一段时间自动执行
定义和用法 setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. 语法 setTimeout(code,millisec) 参数 描述 code 必需.要调用的函数后要执行的 Ja ...
- noip搜索模拟题 骰子
骰子 dice.cpp/c/pas 1s/128M [题目描述] 桌面上有两个特别的骰子.骰子的每一个面,都写了一个不同的数字.设第一个骰子上下左右前后分别为a1, a2, a3, a4, a5, a ...
- JAVA代码之斗地主发牌
理解很好理解,关键是思路 按照斗地主的规则,完成洗牌发牌的动作: 具体规则: 1. 组装54张扑克牌 2. 将54张牌顺序打乱 3. 三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌. ...
- JavaScript 事件对象event
什么是事件对象? 比如当用户单击某个元素的时候,我们给这个元素注册的事件就会触发,该事件的本质就是一个函数,而该函数的形参接收一个event对象. 注:事件通常与函数结合使用,函数不会在事件发生前被执 ...