描述

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

格式

输入格式

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

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

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

输出格式

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

样例1

样例输入1[复制]

3 3 2

1 4

0 1 3

1 1 2

5 2 3

样例输出1[复制]

10

限制

1s

提示

样例说明:

对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。

【题目链接】:http://noi.qz5z.com/viewtask.asp?id=z06

【题解】



如果不考虑有加速器的情况;

那么设f[i]为公交车到达第i个站的时间;

last[i]表示第i个站最晚上车的人的时间;->这个东西很好搞出来的.



f[i] = max(f[i-1],last[i-1])+d[i-1];

f[1] = 0;

通过这个递推可以得到f[1..n]的值;

然后对于每个乘客

sum+=f[b[i]]-t[i];

就是所有乘客不用加速器的总时间了;

接下来考虑用加速器的情况.

这里我们只考虑一个加速器.

k个的话,叠加一下就好;

如果我们在第i-1个地方用1个加速器;

那么d[i-1]会减少1;

则根据f[i] = max(f[i-1],last[i-1])+d[i-1]可知

f[i]也会减少1(max里面的东西都不变);

那么f[i+1]会怎么变呢?

f[i+1] = max(f[i],last[i])+d[i];

这里的f[i]是减少1了,但是你不能保证f[i]比last[i]大。

这里

如果f[i]>last[i]

那么f[i+1]也会减少1.

以此类推

只要f[i]>last[i],那么这个影响就会一直传递下去.

如果不满足f[i]>last[i],那么这个影响就此消失。此后都不会有影响.

即在第i-1的位置用加速器,影响到了f[i..j];使它们的值都减少了1;

这个影响的范围用g[i]表示->在第i个位置用一次加速器,它能影响到的最右端点;



g[n-1] = n;

if (f[i+1]>last[i+1])

****g[i] = g[i+1]

else

****g[i] = i+1;->无论如何肯定是会影响到下一个站的.

看看我们当时是怎么求总时间的?

for (int i = 1;i <= n;i++) sum+=f[b[i]]-t[i];

而我们在第i个站用加速器会让

[i+1,g[i]]这个区间里面的f值都减1;而所有人的t值不变.

所以我们要求的就是有多少个人的b(也即下车的位置)是在i+1到g[i]这个区间里面的;其人数对应的就是需要减去的时间;(因为只用了一个加速器)

这个可以用前缀和搞;->pre[i]表示在i位置以前下车的人有多少.

则寻找使得pre[g[i]]-pre[i]最大的i;(不要忘了dis[i]要大于0!)

然后dis[i]-=1;

sum-=(pre[g[i]]-pre[i])*1

再重新搞一遍f数组,然后重复k次;

(有些人可能在i+1..g[i]这个区间里面上车,但是没有在g[i]之前下车,那么他们的时间不会减少的.因为它们最终下车的站x,f[x]的值不变,(x>g[i]),也就是它们最终到达时间不变.而t即上车时间不变,那么他们并没有因此而获益,这是因为它们要在g[i]那个站(f[i]<=last[i]),等到last[i]才能走,加速器让f[i]减1了,但是此时f[i]

#include <cstdio>
#include <algorithm>
#define rei(x) scanf("%d",&x)
#define rep1(i,x,y) for (int i = x;i <= y;i++) using namespace std; const int MAXN = 1e3+100;
const int MAXM = 1e4+100; int n,m,k;
int dis[MAXN],t[MAXM],a[MAXM],b[MAXM],pre[MAXN];
int f[MAXN],last[MAXN],sum =0,g[MAXN]; int main()
{
//freopen("F:\\rush.txt","r",stdin);
rei(n);rei(m);rei(k);
rep1(i,1,n-1)
rei(dis[i]);
rep1(i,1,m)
{
rei(t[i]);rei(a[i]);rei(b[i]);
last[a[i]] = max(last[a[i]],t[i]);
pre[b[i]]++;
}
rep1(i,1,n)
pre[i] += pre[i-1];
f[1] = 0;
rep1(i,2,n)
f[i] = max(f[i-1],last[i-1]) + dis[i-1];
rep1(i,1,m)
sum += f[b[i]]-t[i];
while (k--)
{
g[n-1] = n;
for (int i = n-2;i >= 1;i--)
if (f[i+1]>last[i+1])
g[i] = g[i+1];
else
g[i] = i + 1;
int j = -1,ma = 0;
rep1(i,1,n-1)
if (pre[g[i]]-pre[i] > ma && dis[i])
ma = pre[g[i]]-pre[i],j = i;
if (j==-1)
break;
dis[j]--;
sum-=pre[g[j]]-pre[j];
rep1(i,2,n)
f[i] = max(f[i-1],last[i-1]) + dis[i-1];
}
printf("%d\n",sum);
return 0;
}

【z06】观光公交的更多相关文章

  1. vijos1741 观光公交 (贪心)

    https://www.vijos.org/p/1741 P1741观光公交 请登录后递交 标签:NOIP提高组2011[显示标签]   描述 风景迷人的小城Y市,拥有n个美丽的景点.由于慕名而来的游 ...

  2. NOIP2011 观光公交

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

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

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

  4. NOIP观光公交

    #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #inc ...

  5. noip 2011观光公交

    P1315 观光公交 95通过 244提交 题目提供者该用户不存在 标签贪心递推2011NOIp提高组 难度提高+/省选- 提交该题 讨论 题解 记录   题目描述 风景迷人的小城Y 市,拥有n 个美 ...

  6. 观光公交 2011年NOIP全国联赛提高组(贪心,递推)

    观光公交 2011年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold       题目描述 Description 风景迷人的小城 Y 市 ...

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

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

  8. luoguP1315 观光公交 题解(NOIP2011)(贪心)

    P1315 观光公交 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include<cm ...

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

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

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

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

随机推荐

  1. 20160218.CCPP体系具体解释(0028天)

    程序片段(01):加法.c 内容概要:字符串计算表达式 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <st ...

  2. 淘宝分类导航条;纯css实现固定导航栏

    效果例如以下: 页面例如以下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...

  3. get_browser()用法

    get_browser()用法 get_browser()函数是用来分析USER_AGENT的,它的执行方法是自动获取客户端的USER_AGENT,然后调用browscap.ini库进行分析得到结果 ...

  4. vue 自定义分页组件

    vue2.5自定义分页组件,可设置每页显示条数,带跳转框直接跳转到相应页面 Pagination.vue 效果如下图: all: small(只显示数字和上一页和下一页): html <temp ...

  5. [python]两种编程思维--面向过程和面向对象

    例如:eg:炒一份西红柿鸡蛋 一.面向过程 面向过程的编程思维,如下 二.面向对象 制作一台炒菜机器人,然后告诉机器人做一道西红柿炒鸡蛋.在这里,我们直接面对的是机器人,而非炒菜的过程,所以这里机器人 ...

  6. ARCGIS刷新的故事

    转自原文章ARCGIS部分刷新 1, IActiveView.Refresh 全局刷新,即重绘地图中的所有内容,是效率最低的一种刷新方法.当数据量大时非常耗时.所以除非绝对必要,一般推荐使用IActi ...

  7. ajax对服务端发送请求

    //兼容处理获取ajax对象 var req = ''; if (window.XMLHttpRequest)    req = new XMLHttpRequest(); else    req = ...

  8. express,中间件(body-parser),req.body获取不到参数(含postman发请求的方法)

    问题描述: 最近在做毕设,express 里边的中间件(body-parser)失效,req.body获取不到任何值,req.query能获取到值.一开始加body-parser中间件是有用的,直到昨 ...

  9. UVA 11646 - Athletics Track || UVA 11817 - Tunnelling the Earth 几何

    题目大意: 两题几何水题. 1.UVA 11646 - Athletics Track 如图,体育场的跑道一圈400米,其中弯道是两段半径相同的圆弧,已知矩形的长宽比例为a:b,求长和宽的具体数值. ...

  10. Eclipse手动配置svn

    1.在Eclipse根目录下建一个任意文件夹(如plugin),在该文件夹下建一个以该插件名命名的文件夹(如SVN).2.将下载下的插件文件解压,plugins和features文件夹复制到该文件夹下 ...