3.观光公交

(bus.cpp/c/pas)

风景迷人的小城 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 该如何安排使用加速器,才能使所有乘客的旅行时间总和最小?

【输入】

输入文件名为 bus.in。

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

和氮气加速器个数。

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

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

【输出】

输出文件名为 bus.out。共一行,包含一个整数,表示最小的总旅行时间。

【输入输出样例】

bus.in   bus.out

3 3 2

1 4

0 1 3

1 1 2

5 2 3    10

【输入输出样例说明】

对 D2 使用 2 个加速器,从 2 号景点到 3 号景点时间变为 2 分钟。

公交车在第 1 分钟从 1 号景点出发,第 2 分钟到达 2 号景点,第 5 分钟从 2 号景点出发, 第 7 分钟到达 3 号景点。

第 1 个旅客旅行时间 7-0 = 7 分钟。 第 2 个旅客旅行时间 2-1 = 1 分钟。 第 3 个旅客旅行时间 7-5 = 2 分钟。 总时间 7+1+2 = 10 分钟。

【数据范围】

对于 10%的数据,k=0; 对于 20%的数据,k=1;

对于 40%的数据,2 ≤ n ≤ 50,1 ≤ m ≤ 1,000,0 ≤ k ≤ 20,0 ≤ Di ≤ 10,0 ≤ Ti ≤ 500;

对于 60%的数据,1 ≤ n ≤ 100,1 ≤ m ≤ 1,000,0 ≤ k ≤ 100,0 ≤ Di ≤ 100,0 ≤ Ti ≤ 10,000;

对于 100% 的数据,1 ≤ n ≤ 1,000 ,1 ≤ m ≤ 10,000 ,0 ≤ k ≤ 100,000 ,0 ≤ Di ≤ 100 ,

0 ≤ Ti ≤ 100,000。

【思路】

贪心。

考虑没有加速器的情况,可以由题目条件求出观光车到达每个车站的时间time,递归求解如下:

     time[i]=max{ time[i-1] , t[i-1] }+d[i-1]

   再考虑有加速器的情况,注意使用一个加速器相当于对于一部分人的时间-1。对于边i使用加速器,一定可以使在i+1站下车的人数时间-1,如果time[i+1]>=t[i+1]则观光车需要等待i+1站的人上车后才能走所以加速器的“加速效果”停止于i+1;否则,加速器的效果可以延续。如果设g[i]表示对i边加速所能延续到的最大车站则有以下递推式:

g[i]=time[i+1]>=t[i+1]? i+1 : g[i+1]

令sum(j)表示到j及以前下车的人数。每次贪心选择sum(g[i])-sum(i)最大及加速效果最优的边进行加速,直到用尽所有的加速器或不能加速。

【代码】

 #include<iostream>
#include<cstring>
using namespace std; const int maxn = +;
struct Node{
int T,from,to;
}a[maxn]; int n,m,K;
int times[maxn],t[maxn],g[maxn],d[maxn];
int sum[maxn]; int main() {
ios::sync_with_stdio(false); cin>>n>>m>>K;
for(int i=;i<n;i++) cin>>d[i];
for(int i=;i<=m;i++) {
cin>>a[i].T>>a[i].from>>a[i].to;
t[a[i].from]=max(t[a[i].from],a[i].T); //t[i]是从 i 出发的最大时间
sum[a[i].to] ++;
}
for(int i=;i<=n;i++) //到达 i 及 i 之前的人数
sum[i] += sum[i-]; int ans=;
times[]=t[];
for(int i=;i<=n;i++)
times[i]=max(times[i-],t[i-])+d[i-];
for(int i=;i<=m;i++) { //m //统计没有加速器的 ans
ans += times[a[i].to]-a[i].T;
}
while(K--) {
g[n] = g[n-] = n;
for(int i=n-;i;i--) //维护 g
g[i]=(times[i+]<=t[i+])? i+ : g[i+]; int _max=,k;
for(int i=;i<n;i++) { //找到使用加速器最有效的边
if(sum[g[i]]-sum[i]>_max && d[i]>) { //d[i]>0
_max=sum[g[i]]-sum[i];
k=i;
}
} if(!_max) break; ans -= _max; //使用加速器缩短时间
d[k] --; times[]=t[];
for(int i=;i<=n;i++) //维护 time
times[i]=max(times[i-],t[i-])+d[i-];
} cout<<ans;
return ;
}

NOIP2011 观光公交的更多相关文章

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

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

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

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

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

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

  4. [NOIP2011]观光公交 题解

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

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

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

  6. NOIP2011 观光公交 加强版

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

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

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

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

    Luogu 1315 [NOIP2011]观光公交 (贪心) Description 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供 ...

  9. 洛谷P1315 [NOIP2011提高组Day2T3] 观光公交

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

随机推荐

  1. @Entity设置OneToMany

    Hibernate设置bean映射数据库的方式有配置模式与注解模式,下面通过注解模式配置OneToMany @Entity @Table(name="csdnbbs_sys_catalog& ...

  2. 深入js的面向对象学习篇——温故知新(一)

    在学习设计模式前必须要知道和掌握的***. 为类添加新方法: Function.prototype.method = function(name,fn) { this.prototype[name] ...

  3. wordpress如何删除没有文章的tags标签

    wordpress站点除了可以按博客category分类外,还可以在写文章的时候适当添加tags标签(当然,if you are lazy,哈哈,可以安装auto tag插件来实现),发布的posts ...

  4. Java中堆、栈、常量池分析

    栈用于存储局部变量,包括基本类型的变量(方法语句块内部定义的变量.方法中的形参).引用类型的变量,它们都是存储在各自的方法栈中,随着方法的执行完成而消失: 堆用于存储引用类型变量所指向的对象,包括普通 ...

  5. 写给 iOS 开发者的 Hopper + lldb 简介

    最近,关于 @Steipete 在Radar发布的帖子,笔者看到很多人在问「你是怎么理解那个伪代码的」.笔者想写博客已经有一段时间了,现在正好就此发表第一篇博文.笔者在一个叫 Hopper 的工具上花 ...

  6. Oracle 学习笔记(一)

    1.连接数据库命令: conn 用户名/密码,当用特权身份连接时,要加上as sysdba 2.修改密码: passw(ord),如果要修改其他人的密码,需要用sys或者system登录 3.显示当前 ...

  7. APK签名校验绕过

    APK签名校验绕过 Android JNI 获取应用签名 android apk 防止反编译技术第一篇-加壳技术 android apk 防止反编译技术第五篇-完整性校验 利用IDA Pro反汇编程序 ...

  8. red5研究(一):下载,工程建立、oflaDemo安装、demo测试

    一.red5下载.添加工程到myeclipse 1,从官网上下载red51.01版本(我下载的是red51.0的版本),下载链接http://www.red5.org/downloads/red5/1 ...

  9. Android ActionBar通过Tab进行不同的Fragment之间的交换

    ActionBar的使用常见于4.0系统,其Tab的使用挺广泛的. 在ActionBar中添加标签(Tabs),每个标签对应的是一个Fragment,点击不同的Tab时,就会切换到对应的Fragmen ...

  10. node.js EventEmitter发送和接收事件

    EventEmitter是nodejs核心的一部分.很多nodejs对象继承自EventEmitter,用来处理事件,及回调.api文档地址: http://nodejs.org/api/events ...