[USACO 2009 Feb Gold] Fair Shuttle (贪心+优先队列)

题目大意:有N个站点的轻轨站,有一个容量为C的列车起点在1号站点,终点在N号站点,有K组牛群,每组数量为Mi(1≤Mi≤N),行程起点和终点分别为Si和Ei(1≤Si<Ei≤N)。计算最多有多少头牛可以搭乘轻轨。

一道经典的贪心题目,每当一头牛上车的时候,如果超载,我们就优先踢出去行程终点比较远的那部分牛

而 踢出哪些行程终点较远的牛 以及 哪些在车上的牛在这站到达了终点,都可以用优先队列来维护,复杂度约为

贴上代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <queue>
 4 #include <cstring>
 5 #define N 50005
 6 #define ll long long
 7 using namespace std;
 8
 9 int k,n,c,ans;
10 int sum[N];
11 struct COW{
12     int x,y,w;
13 }cow[N];
14 int cmp(COW s1,COW s2) {return s1.x<s2.x;}
15 struct node1{
16     int id;
17     friend bool operator<(const node1 &s1,const node1 &s2)
18     {return cow[s1.id].y > cow[s2.id].y;}
19 };
20 node1 ins1(int idd){node1 w;w.id=idd;return w;}
21 struct node2{
22     int id;
23     friend bool operator<(const node2 &s1,const node2 &s2)
24     {return cow[s1.id].y < cow[s2.id].y;}
25 };
26 node2 ins2(int idd){node2 w;w.id=idd;return w;}
27 int solve()
28 {
29     sort(cow+1,cow+k+1,cmp);
30     priority_queue<node1>q1;
31     priority_queue<node2>q2;
32     int j=1,cnt=0;
33     for(int i=1;i<=n;i++)
34     {
35         while(!q1.empty())
36         {
37             node1 p=q1.top();
38             if(cow[p.id].y==i)
39             {
40                 q1.pop();
41                 ans+=sum[p.id];
42                 cnt-=sum[p.id];
43                 sum[p.id]=0;
44             }else{
45                 break;
46             }
47         }
48         while(cow[j].x==i)
49         {
50             q1.push(ins1(j));
51             q2.push(ins2(j));
52             cnt+=cow[j].w;
53             sum[j]=cow[j].w;
54             j++;
55         }
56         while(cnt>c)
57         {
58             node2 p=q2.top();
59             if(cnt-sum[p.id]>c)
60             {
61                 q2.pop();
62                 cnt-=sum[p.id];
63                 sum[p.id]=0;
64             }else{
65                 sum[p.id]-=(cnt-c);
66                 cnt=c;
67             }
68         }
69     }
70     return ans;
71 }
72
73 int main()
74 {
75     scanf("%d%d%d",&k,&n,&c);
76     for(int i=1;i<=k;i++) scanf("%d%d%d",&cow[i].x,&cow[i].y,&cow[i].w);
77     printf("%d",solve());
78     return 0;
79 }

原文地址:https://www.cnblogs.com/guapisolo/p/9696923.html

时间: 2024-11-05 13:38:29

[USACO 2009 Feb Gold] Fair Shuttle (贪心+优先队列)的相关文章

BZOJ1577 USACO 2009 Feb Gold 1.Fair Shuttle Solution

权限题,不给传送门啦!在学校OJ上交的.. 有些不开心,又是一道贪心,又是一个高级数据结构的模板,又是看了别人的题解还写崩了QAQ,蒟蒻不需要理由呀. 正经题解: 首先,我们可以由「显然成立法」得出,只要我们按照右端点排序,然后能塞多少就塞多少就一定是最优哒! 你们可以YY一下,如果一堆牛能下车就赶紧下是不是可以得出最优的呢,我感觉不对但是他们都说对 然后就是很基本的线段树维护区间的查询和修改了. 需要注意的一个小地方是如果是线段树修改区间右端点是要-1的,这个很显然. 下面是具体实现: 1 /

BZOJ1579 USACO 2009 Feb Gold 3.Revamping Trails Solution

标题效果:一个N积分m无向图边.它可以是路径k右边缘值变0,确定此时1-n最短路径长度. Sol:我以为我们考虑分层图,图复制k+1部分,每间0~k一层.代表在这个时候已经过去"自由边缘"文章编号. 层与层之间的边权值为0且为单向由上层指向下层. 这样我们以0层的1点做单源最短路径.每一层的n点的距离最小值即为答案. 仅仅只是这种点数为O(K*N),边数为O(K*M),比較慢. 我的做法是,对每一层使用heap-dijkstra算法由本层的原点更新这一层的最短路长度.然后显然能够用O(

【POJ3666】【USACO 2008 Feb Gold】 2.Cow Game 动规

题意:有若干个数,然后可以花费i的代价让某个数+i或者-i. 现在要求让你把序列排成不升或者不降,问最小代价. 题解: 首先可以证明,最优花费下最后所有的数都可以是现在的某个数: 证:如果两个数调整后在两个数中间,那么可以把两个数都变为其中一个数,而代价显然是等同的. 这个出来后就好做了. 我们可以先离散化一下,然后f[i][j]表示第i个数变为j时1~i这些数保持非严格单调的最小花费 转移时f[i][j]不必n*n枚举,可以维护一个前缀最优(非常水),然后O(1)转移. 然后做一遍非升,一遍非

USACO 2017 FEB Gold visitfj 最短路

题意 有一幅n*n的方格图,n <= 100,每个点上有一个值.从(1,1)出发,走到(n,n),只能走四联通.每走一步花费t,每走三步需要花费走完三步后到达格子的值.求最小花费的值. 拆点,dis[i][j]表示到达第i个点时走的总步数模3等于j时的最小花费值. #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorith

道路翻新 (Revamping Trails, USACO 2009 Feb)

题意:给定m<=50000的1-n有联通的图,求最多可以使K<=20条边变为0的情况下的最短路是多少.. 思路:简单的分层图最短路,对于每个点拆成K个点.. 然后求一边最短路.. code: 1 /* 2 * Author: Yzcstc 3 * Created Time: 2014/11/5 19:25:47 4 * File Name: revamp.cpp 5 */ 6 #include<cstdio> 7 #include<iostream> 8 #includ

BZOJ1584 USACO 2009 Mar Gold 2.Cleaning Up

题目大意:有长度为N的颜色段,共有m种颜色,要将其划分成若干段,每一段的费用为这一段的不同颜色的数目的平方.求最小总费用. Sol: 首先我们注意到答案不超过n,因为我们显然可以将每一个划分为一段,答案为n. 于是每一段的颜色总数不超过sqrt(n). 因此我们维护最后出现的sqrt(n)种颜色最后出现的位置,进行转移. 总的时间复杂度为O(n*sqrt(n)). Code: #include <cmath> #include <cstdio> #include <cstri

BZOJ1585 USACO 2009 Mar Gold 3.Earthquake Damage 2

题目大意:与http://blog.csdn.net/wyfcyx_forever/article/details/39345281这个相近.只是求的是损坏节点的最小数目. Sol: 拆点最小割. S->1 c=INF 提到的点x x'->T c=INF 对于每个点x,为1或是提到的点 x->x' c=INF 对于每个点x,不为1且不是提到的点 x->x' c=1 对于原图每条边x->y x'->y c=INF y'->x c=INF 然后强大的ISAP模板水过.

【BZOJ】【3398】【USACO 2009 Feb】Bullcow 牡牛和牝牛

组合计数 排列组合求总方案数 这个可以用一个一维的动态规划解决: f[i][0]表示第i头牛是牝牛的方案数 f[i][1]表示第i头牛是牡牛的方案数 则转移为:f[i][0]=f[i-1][0]+f[i-1][1]; f[i][1]=f[i-K-1][0]+f[i-K-1][1]; 常数优化:将取模运算改为if判断语句……可从20ms降为16ms 1 /************************************************************** 2 Problem

USACO·2012·Feb Bronze &amp;&amp; 2009·Open Gold

Rope Folding [Brian Dean, 2012] 时间限制: 1 Sec 内存限制: 128 MB 题目描述 Farmer John has a long rope of length L (1 <= L <= 10,000) that he uses for various tasks around his farm. The rope has N knots tied into it at various distinct locations (1 <= N <=