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;
}

转载于:https://www.cnblogs.com/SYCstudio/p/7499341.html

Luogu 1315 【NOIP2011】观光公交 (贪心)相关推荐

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

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

  2. NOIP2011 观光公交

    话说,我终于AC了这个题 这是一个贪心,说实话开始做的时候......完全没看出来QAQ.. 可能有人说这是个dp,但这真不是(dalao请无视) 这真的只是个贪心.... 首先对于每个点当然是能走就 ...

  3. 【洛古 P1315】 [NOIP2011 提高组] 观光公交

    [NOIP2011 提高组] 观光公交 题目背景 感谢 @Transhumanist 提供的一组 Hack 数据 题目描述 风景迷人的小城 Y 市,拥有 n n n 个美丽的景点.由于慕名而来的游客越 ...

  4. 【做题记录】[NOIP2011 提高组] 观光公交

    P1315 [NOIP2011 提高组] 观光公交 我们想在 \(k\) 次加速每一次都取当前最优的方案加速. 考虑怎样计算对于每一条边如果在当前情况下使用加速器能够使答案减少的大小. 如果当前到达某 ...

  5. Luogu 1970 NOIP2013 花匠 (贪心)

    Luogu 1970 NOIP2013 花匠 (贪心) Description 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定把这排中的一部分花移走,将剩下的留在原地,使 ...

  6. 观光公交削弱_削弱Web开发人员和Internet的7大障碍

    观光公交削弱 As a web developer I periodically take a step back from the text editor and look at the lands ...

  7. 观光公交削弱_您的工作可能如何削弱您的技术技能

    观光公交削弱 对简单的入门和故障安全环境的渴望使开发人员感到自我破坏. 现代软件应用程序是巨大的. 甚至小型公司产品也可以由抽象的层次组成. 根据与您最紧密合作的那一层,您可能会错过很多东西. Mar ...

  8. 【NOIP2011 Day 2】观光公交

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

  9. 洛谷P1315 观光公交

    SB贪心......暴露了我代码能力巨弱的本质. 题面 解:首先我们应该想到DP(但是我想到了贪心......) 然后分析题目本质,每个点有个限制,最早开走时间不得早于最晚上车时间. 然后我们就可以把 ...

最新文章

  1. 从Qcheck 1.3 不能在不同操作系统上运行问题(chro124、chro342)说开来------
  2. 动态加载子节点_微信小游戏开发之场景切换和常驻节点传递数据
  3. 170页PPT入门深度强化学习! 汪荣贵 图灵人工智能 昨天
  4. 在Flutter中嵌入Native组件的正确姿势
  5. python not函数_python 函数
  6. 关于虚拟机vmware共享虚拟网卡上网
  7. 应对Windows XP黑屏
  8. 一步步编写操作系统 23 重写主引导记录mbr
  9. python 密度聚类 使用_使用python+sklearn实现硬币图像上的结构化Ward层次聚类演示...
  10. LNMP3.0一键安装
  11. 基于python 爬虫_基于python的爬虫(一)
  12. spss20安装许可证代码_SPSS 22下载安装教程
  13. c语言报告 列主元lu分解,列主元LU分解法 C++程序
  14. 淘宝用户行为分析(python+mysql+tableau)
  15. 互联网后端的主流编程语言是啥?不是Python?
  16. Spring Security OAuth2.0 认证协议【15】实现QQ第三方登录
  17. 物联网应用技术和计算机应用技术,物联网应用技术专业介绍
  18. 计算机链接投影仪后不显示桌面,win10系统连接投影后不显示桌面图标怎么办
  19. 360浏览器各历史版本大全和bug汇总(及历史版本官方下载地址)
  20. 小米手机夜间模式在哪设置?仅需2个步骤

热门文章

  1. 十强队伍来了!网易云信 Innovation 2022 开发者大赛决赛名单公布
  2. 初心始终 殊途同归 | SCTF同期个人能力认证考核专场报名开启
  3. oracle命名规则
  4. ICCV2019(Segmentation):ShelfNet-论文解读《ShelfNet for Fast Semantic Segmentation》
  5. 2018年舆情产品小总结
  6. oracle 数据库表的字段类型修改为clob类型报错及解决方法
  7. 看影片《明日边缘》有感
  8. MTK平台点亮sensor以及mtk开机初始化
  9. head first java勘误_《深入解析Oracle》一书勘误表
  10. C++播放音乐和MFC的messagebox用法