Luogu 1315 【NOIP2011】观光公交 (贪心)

Description

风景迷人的小城Y 市,拥有n 个美丽的景点。由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务。观光公交车在第0 分钟出现在1号景点,随后依次前往2、3、4……n 号景点。从第i 号景点开到第i+1 号景点需要Di 分钟。

任意时刻,公交车只能往前开,或在景点处等待。

设共有m 个游客,每位游客需要乘车1 次从一个景点到达另一个景点,第i 位游客在Ti 分钟来到景点Ai,希望乘车前往景点Bi(Ai<bi)。为了使所有乘客都能顺利到达目的地,公交车在每站都必须等待需要从该景点出发的所有乘客都上车后才能出发开往下一景点。

假设乘客上下车不需要时间。

一个乘客的旅行时间,等于他到达目的地的时刻减去他来到出发地的时刻。因为只有一辆观光车,有时候还要停下来等其他乘客,乘客们纷纷抱怨旅行时间太长了。于是聪明的司机ZZ 给公交车安装了k 个氮气加速器,每使用一个加速器,可以使其中一个Di 减1。对于同一个Di 可以重复使用加速器,但是必须保证使用后Di 大于等于0。

那么ZZ 该如何安排使用加速器,才能使所有乘客的旅行时间总和最小?

Input

第1 行是3 个整数n, m,k,每两个整数之间用一个空格隔开。分别表示景点数、乘客数和氮气加速器个数。

第2 行是n-1 个整数,每两个整数之间用一个空格隔开,第i个数表示从第i个景点开往第i+1 个景点所需要的时间,即Di。

第3 行至m+2 行每行3 个整数Ti, Ai,Bi,每两个整数之间用一个空格隔开。第i+2 行表示第i 位乘客来到出发景点的时刻,出发的景点编号和到达的景点编号。

Output

共一行,包含一个整数,表示最小的总旅行时间。

Sample Input

3 3 2

1 4

0 1 3

1 1 2

5 2 3

Sample Output

10

Http

Luogu:https://www.luogu.org/problem/show?pid=1315

Source

贪心

解决思路

首先可以贪心的想到,要让每一个加速器的效应最大,那么要让其作用的人最多,所以我们可以想到是一个取最大值的操作。

再来考虑每一个景点。首先如果当前公交车到达某一个景点后还要等乘客,这时在前面这条路上使用加速器是不实用的,因为同样还要等,没有必要浪费。即我们可以得出一个结论,就是公交车从一个景点出发的理论最晚时间(LastTime)就是这个景点的最后来的那个人的时间。

所以,我们可以先把不使用加速器的总时间算出来,然后再最优地减去最多的时间。

不使用加速器的总时间是多少呢?

\[Ans=\sum_{i-1}^{m}LeaveTime[Ranger[i]]-PeopleTime[i]
\]

\(Ranger[i]\)代表第i个人的终点景点

\(PeopleTime[i]\)代表第i个人到来的时间

\(LeaveTime[i]\)表示从i点出发的实际时间,那么\(LeaveTime[i]=max(LeaveTime[i-1],LastTime[i-1])+Dist[i-1]\)

其中\(Dist[i-1]\)表示第i-1个景点到景点i消耗的时间。

从计算总时间的式子可以看出,\(PeopleTime[i]\)是不会变的,我们能减少的就是\(LeaveTime[]\)这一部分。

也就是说,我们要使得每一个人尽可能地早下车

然后考虑如何取这个最优

首先需要知道的是,如果我们对一条路上的时间-1,那么它影响的不仅仅只是这条路,还可能会影响到后面的若干条路。如果\(LeaveTime[i]>LastTime[i]\),也就是说在第i个点上,最晚来的那个人也要等一下,那么如果公交车来早1,这个景点的所有人就都可以早出发1,这也就导致后面的时间都会提早1,向后传递。否则,若在第i个景点,公交车本来就要等最后一个人来,那么此时公交车来早1,同样还是要等到那个时间,后面的时间不会因此改变,所以不会影响后面。

具体在实现上面的计算时,我们用LastInfluence[i]代表第i+1个景点最远能影响到的景点。为什么这里是第i+1呢?因为实际上我们在计算影响时是根据两点之间的边来算的,但后面统计又要用到人,所以把边换成对点的操作。

那么对于从i到\(LastInfluence[i]\)这其中我们要统计什么呢?

结合我们上面所说的让每个人尽早下车,我们统计一下每一个景点下车的人数,那么如果我们把第i条边的时间-1,那么对于景点i到景点\(LastInfluence[i]\)这其中所有下车的人的时间都-1。那么现在的问题就是要找出这些影响区间所覆盖的下车人数最大。简单来说,就是区间最大和。这个最大和,我们可以用前缀和来维护。

注意,每使用一次加速器,要把LeaveTime[i]重新统计,因为使用加速器后会有一条边的时间减少,对应的会影响一段区间的时间,所以要重新计算。

简单地总结一下,此题的步骤就是

1.求出不使用加速器时的总时间

2.每一次找出一个影响区间覆盖的下车人数最多的区间,减去对应的答案,并重新统计实际出发时间,以此进行下次求值。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; const int maxN=2000;
const int maxM=20000;
const int inf=2147483647; int n,m,K;
int Dist[maxN];
int EndSum[maxN];//EndSum[i]表示在i号位置下车的人的数量,输入完后,再用来计算前缀和
int Rangel[maxM];//人出发的景点
int Ranger[maxM];//人到达的景点
int PeopleTime[maxM];//人到达景点的时间
int LastTime[maxN];//最后到达的人的时间
int LeaveTime[maxN];//离开的时间
int LastInfluence[maxN];//影响区间 void init();//计算LeaveTime数组 int main()
{
memset(LastTime,0,sizeof(LastTime));
memset(EndSum,0,sizeof(EndSum));
scanf("%d%d%d",&n,&m,&K);
for (int i=1;i<n;i++)
scanf("%d",&Dist[i]);
Dist[n]=0;
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&PeopleTime[i],&Rangel[i],&Ranger[i]);
EndSum[Ranger[i]]++;
LastTime[Rangel[i]]=max(LastTime[Rangel[i]],PeopleTime[i]);
}
int Ans=0;
for (int i=1;i<=n;i++)//计算前缀和
EndSum[i]+=EndSum[i-1];
init();
for (int i=1;i<=m;i++)//统计不使用加速器时的总时间
Ans+=LeaveTime[Ranger[i]]-PeopleTime[i];
while (K--)
{
LastInfluence[n]=LastInfluence[n-1]=n;//倒着推出每一个景点向后最远能影响到哪里
for (int i=n-2;i>=1;i--)
LastInfluence[i]=(LeaveTime[i+1]<=LastTime[i+1])?i+1:LastInfluence[i+1];//感谢@泪眼问花花不语 找到一个错误
int nowmax=0,id;//求出最大区间和
for (int i=1;i<n;i++)
if ((EndSum[LastInfluence[i]]-EndSum[i]>nowmax)&&(Dist[i]!=0))
{
nowmax=EndSum[LastInfluence[i]]-EndSum[i];
id=i;
}
Dist[id]--;//减去使用加速器造成的效果
Ans-=nowmax;
init();//重新计算LeaveTime
}
printf("%d\n",Ans);
return 0;
} void init()
{
LeaveTime[1]=LastTime[1];
for (int i=2;i<=n;i++)
LeaveTime[i]=max(LastTime[i-1],LeaveTime[i-1])+Dist[i-1];
return;
}

Luogu 1315 【NOIP2011】观光公交 (贪心)的更多相关文章

  1. [luogu]P1315 观光公交[贪心]

    [luogu]P1315 [NOIP2011]观光公交 ——!x^n+y^n=z^n 题目描述 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车, ...

  2. $Noip2011/Luogu1315$ 观光公交 贪心

    $Luogu$ $Sol$ 觉得这题贪心要想很多事情,不适合我这种没脑子选手$ovo$.看题解还理解了很久. 最开始是这样想的:把所有的路段上的乘客按大小排个序用加速器就好了,这个想法被自己轻松$ha ...

  3. NOIP2011 观光公交

    3.观光公交 (bus.cpp/c/pas) 风景迷人的小城 Y 市,拥有 n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特 意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第 ...

  4. [NOIP2011] 观光公交(贪心)

    题目描述 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第 0 分钟出现在 1号景点,随后依次前往 2 ...

  5. 贪心(模拟费用流):NOIP2011 观光公交

    [问题描述] 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第0 分钟出现在1号景点,随后依次前往2. ...

  6. [搬运] [贪心]NOIP2011 观光公交

    推荐这篇题解:http://www.cnblogs.com/Blacko/archive/2013/10/18/3376597.html 只不过这篇题解有一些细节没有说清,但建议自己思考- Codes ...

  7. 题解【洛谷P1315】[NOIP2011]观光公交

    题目描述 风景迷人的小城 Y 市,拥有 \(n\) 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务. 观光公交车在第 \(0\) 分钟出现在 \( ...

  8. NOIP2011 观光公交 加强版

    传送门 题目大意 给定从左到右的$n$个车站以及两两之间通行的需要的时间. 有$m$个人,第$i$个人会在$T_i$时刻出现在$a_i$车站,目的地是$b_i$. 一辆车第$0$时刻出现在一号站台,从 ...

  9. 洛谷 P1315 观光公交 —— 贪心

    题目:https://www.luogu.org/problemnew/show/P1315 问题是想不明白改动一条边会对后面造成怎样的影响: 实际上影响的会是一段,当某个车站出发时间受其来人牵制时, ...

  10. [NOIP2011]观光公交 题解

    题目大意: 就省了吧 思路: 应该算是贪心. 不难发现,加速只对所有在使用加速器之后连续的一段下车时不用等人的站点下车的人有用.这非常重要. 先算出不加速时的和,并预处理出每个站点最迟到的人的时间.每 ...

随机推荐

  1. 【下一代核心技术DevOps】:(四)私有镜像库阿里云Docker服务使用

    1.使用阿里云镜像库有很多优点 稳定可靠,阿里技术,放心使用. 国内cdn多节点加速,下载速度非常快 可以和阿里云Git代码集成,不需要第三方CI工具,当然带的自动构建服务也可以和其他的Git库集成, ...

  2. Peer Programming Project: 4 Elevators Scheduler 学号后三位 157,165

    1.Advantages and disanvantages of Peer Programming advantages The code are constantly validated by t ...

  3. 软件工程实践作业2 --梭哈游戏(java) 实践报告

    一,题目简介: 1.创建一副扑克牌 7------k 加入到集合对象中2.对扑克牌洗牌3.定义参与游戏的玩家的人,通过键盘输入,限定人数2-54.人数符合要求继续执行,不符合退出5.对玩家发牌,每个人 ...

  4. PAT 1066 图像过滤

    https://pintia.cn/problem-sets/994805260223102976/problems/994805266514558976 图像过滤是把图像中不重要的像素都染成背景色, ...

  5. ModSecurity is an open source, cross-platform web application firewall (WAF) module.

    http://www.modsecurity.org/ ModSecurity is an open source, cross-platform web application firewall ( ...

  6. activiti-explorer disable demo

    https://community.alfresco.com/thread/203012-activiti-explorer engine.properties # demo data propert ...

  7. 变更RHEL(Red Hat Enterprise Linux 5.8)更新源使之自动更新

    HP 4411s Install Red Hat Enterprise Linux 5.8) pick up from http://blog.chinaunix.net/uid-423637-id- ...

  8. [cnbeta]华为值多少钱,全世界非上市公司中估值最高的巨头

    华为值多少钱,全世界非上市公司中估值最高的巨头 https://www.cnbeta.com/articles/tech/808203.htm   小米.美团都曾表达过不想.不急于上市,但没人信,所以 ...

  9. CMake--Set用法

    CMake中的set用于给一般变量,缓存变量,环境变量赋值. cmake官方文档set set(<variable> <value> [[CACHE <type> ...

  10. ORA-01654 : 表空间不足

    参考: Oracle表空间不足ORA-01654 查看表空间和表的使用率 ORA-01654 索引 无法通过 表空间扩展 Oracle 查看表空间的大小及使用情况sql语句 一.基础查询 1.查看表空 ...