bzoj1745[Usaco2005 oct]Flying Right 飞行航班*

bzoj1745[Usaco2005 oct]Flying Right 飞行航班

题意:

n个农场,有k群牛要从一个农场到另一个农场(每群由一只或几只奶牛组成)飞机白天从农场1到农场n,晚上从农场n到农场1,上面有c个座位,问最多可以满足多少只牛的要求。n≤10000,k≤50000,c≤100。

题解:

用类似贪心的方法做,现将每个农场出发的牛组织成链表。先求早上:当飞机到达每个农场时,先让到达的奶牛下机,接着如果飞机未满,则将其填满,之后枚举剩下的奶牛,如果它们的目的地比坐在飞机上面的奶牛目的地近,就将其替换为当前奶牛,这一过程可以用multiset维护。晚上所有过程都倒过来再做一次即可。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <set>
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 #define maxn 10010
 7 using namespace std;
 8
 9 inline int read(){
10     char ch=getchar(); int f=1,x=0;
11     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}
12     while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
13     return f*x;
14 }
15 multiset<int,greater<int> >st1;
16 multiset<int>st2;
17 int n,m,k,now,ans; struct nd{int t,w,n;}nds[2][maxn*5]; int ess[2],g[2][maxn];
18 int main(){
19     n=read(); m=read(); k=read();
20     inc(i,1,n){
21         int x=read(),y=read(),z=read();
22         if(x<y)nds[0][++ess[0]]=(nd){y,z,g[0][x]},g[0][x]=ess[0];
23         else nds[1][++ess[1]]=(nd){y,z,g[1][x]},g[1][x]=ess[1];
24     }
25     now=0;
26     inc(i,1,m){
27         if(st1.find(i)!=st1.end()){int x=st1.erase(i); ans+=x; now-=x;}
28         for(int j=g[0][i];j;j=nds[0][j].n){
29             while(now<k&&nds[0][j].w)st1.insert(nds[0][j].t),nds[0][j].w--,now++;
30             if(now==k){
31                 while(*st1.begin()>nds[0][j].t&&nds[0][j].w)
32                     st1.erase(st1.begin()),st1.insert(nds[0][j].t),nds[0][j].w--;
33             }
34         }
35     }
36     now=0;
37     for(int i=m;i>=1;i--){
38         if(st2.find(i)!=st2.end()){int x=st2.erase(i); ans+=x; now-=x;}
39         for(int j=g[1][i];j;j=nds[1][j].n){
40             while(now<k&&nds[1][j].w)st2.insert(nds[1][j].t),nds[1][j].w--,now++;
41             if(now==k){
42                 while(*st2.begin()<nds[1][j].t&&nds[1][j].w)
43                     st2.erase(st2.begin()),st2.insert(nds[1][j].t),nds[1][j].w--;
44             }
45         }
46     }
47     printf("%d",ans); return 0;
48 }

20161115

时间: 2024-10-13 23:26:32

bzoj1745[Usaco2005 oct]Flying Right 飞行航班*的相关文章

bzoj1745: [Usaco2005 oct]Flying Right 飞行航班(贪心+map)

之前做过一道基本一样的题目,抽象出来就是有个容量为c的载体,一些线段上某个点到另一个点要运输w个东西,求从头到尾最多能运多少东西. 这种模型可以用贪心做,用map,map[r]表示r的那个点,我们准备运多少头牛到那里,但是还没运到. 用map的好处是不管是插入还是删除,它都按坐标从小到大排. 那么先把所有的边按左端点从小到大排,对于当前边, 容量未满的时候,直接加入map 容量满的时候,若map中最大的坐标比这条边的右端点要大,那么显然用当前边替换会更好. 运到的怎么处理呢? 当我们枚举到这个点

1684: [Usaco2005 Oct]Close Encounter

1684: [Usaco2005 Oct]Close Encounter Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 387  Solved: 181[Submit][Status][Discuss] Description Lacking even a fifth grade education, the cows are having trouble with a fraction problem from their textbook. Pl

bzoj1684[Usaco2005 Oct]Close Encounter*

bzoj1684[Usaco2005 Oct]Close Encounter 题意: 找一个分数它最接近给出一个分数.你要找的分数的分子分母的范围在1..32767. 题解: 枚举所求分数的分子,用其乘上给出分数得到一个浮点数分母,比较分母向上/下取整所得分数与答案比较. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #defi

BZOJ 1684: [Usaco2005 Oct]Close Encounter

题目 1684: [Usaco2005 Oct]Close Encounter Time Limit: 5 Sec  Memory Limit: 64 MB Description Lacking even a fifth grade education, the cows are having trouble with a fraction problem from their textbook. Please help them. The problem is simple: Given a

BZOJ(begin) 1333 [Usaco2005 Oct]Allowance 津贴:贪心【给硬币问题】

题目链接:http://begin.lydsy.com/JudgeOnline/problem.php?id=1333 题意: 有n种不同币值的硬币,并保证大币值一定是小币值的倍数. 每种硬币的币值为val,数量为cnt. 每个月你要给Bessie发金额为c的津贴(可以比c多,但不能少). 问你最多能发多少个月. 题解: 贪心. 贪心策略: (1)如果能恰好凑出c的钱,则应尽可能使用大币值的硬币. (2)如果不能恰好凑出,则应让花的冤枉钱尽可能少. 实现: 先按币值从大到小排序... (1)在保

【BZOJ】1684: [Usaco2005 Oct]Close Encounter(暴力+c++)

http://www.lydsy.com/JudgeOnline/problem.php?id=1684 这货完全在考精度啊.. 比如奇葩 (llf)a/b*i (llf)(a/b*i)和(llf)(a/b)*i和(llf)(a/b)*(llf)i 这两货竟然不通????上边的能对,下边的就错了?? 噗. 全部都要..(llf)a/(llf)b*(llf)i..... 这样才不会错.. T_T 教训吸取了. #include <cstdio> #include <cstring>

bzoj 1684: [Usaco2005 Oct]Close Encounter【数学(?)】

枚举分母,然后离他最近的分子只有两个,分别判断一下能不能用来更新答案即可 #include<iostream> #include<cstdio> #include<cmath> using namespace std; int a,b,aa,ab; double mx=10; void wk(int x,int y) { if(x*b==y*a) return; if(fabs((double)x/y-(double)a/b)<mx) { mx=fabs((dou

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

TIMESTEN安装配置指南-中文版

TimesTen内存数据库 第一章 Cache Connect to Oracle概念 TimesTen数据交换技术提供在Oracle数据库和TimesTen数据管理器之间进行连接和双向数据传送.数据交换技术也使得能够方便的捕获和处理进入到TimesTen数据管理器的大流量事件流,而且能进行并发传送数据到Oracle数据库. TimesTen同意通过创建cache group来快速缓存Oracle数据,以在TimesTen中映射一个或多个Oracle表. 同意快速缓存Oracle数据的Times