题目描述

风景迷人的小城 \(Y\) 市,拥有 $n $个美丽的景点。

由于慕名而来的游客越来越多,\(Y\) 市特 意安排了一辆观光公交车,为游客提供更便捷的交通服务。

观光公交车在第 \(0\) 分钟出现在 \(1\) 号景点,随后依次前往 $2、3、4……n $号景点。从第 \(i\) 号景点开到第 \(i+1\) 号景点需要 \(D_i\) 分钟。

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

设共有 \(m\) 个游客,每位游客需要乘车 \(1\) 次从一个景点到达另一个景点,第 \(i\) 位游客在

\(T_i\) 分钟来到景点 \(A_i\),希望乘车前往景点 \(B_i(A_i<B_i)\)。为了使所有乘客都能顺利到达目的地,

公交车在每站都必须等待需要从该景点出发的所有乘客都上车后才能出发开往下一景点。

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

一个乘客的旅行时间,等于他到达目的地的时刻减去他来到出发地的时刻。

因为只有一 辆观光车,有时候还要停下来等其他乘客,乘客们纷纷抱怨旅行时间太长了。

于是聪明的司 机$ ZZ$ 给公交车安装了 \(k\) 个氮气加速器,每使用一个加速器,可以使其中一个 \(D_i\) 减 \(1\)。对于 同一个 \(D_i\) 可以重复使用加速器,但是必须保证使用后 \(D_i\) 大于等于 \(0\)。

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

Input

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

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

第 \(3\) 行至 \(m+2\) 行每行 \(3\) 个整数 \(T_i, A_i, B_i\),每两个整数之间用一个空格隔开。第$ i+2$ 行表 示第 \(i\) 位乘客来到出发景点的时刻,出发的景点编号和到达的景点编号.

对于 \(100\%\)的数据,\(1 <=n <=1,000,1 <=m <=10,000,0 <=k <=100,000,0 <=D_i <=100,0 <=T_i <=100,000\)

Output

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

Sample Input

3 3 2
1 4
0 1 3
1 1 2
5 2 3

Sample Output

10

一道贪心鬼题,\(O(n*k)\)可以卡过。。。

首先,我们要先打出没有加速器的代码。

定义:\(A[i]\)为到\(i\)点的最小时间,\(L[i]\)为起始点为\(i\)的最迟的出发时间,\(D[i]\)为\(i\)到\(i+1\)的路径长度,\(B[i]\)为第\(i\)个人的终点,\(T[i]\)为第\(i\)个人的出发时间。

很显然\(A[i]=max(A[i-1],L[i-1])+D[i-1]\)。

有\(Ans=\sum_{i=1}^{m}A[B[i]]-T[i]\)。

转换一下,\(Ans=-\sum_{i=1}^{m}T[i]+\sum_{i=1}^{m}A[B[i]]\)。

设\(t\)为\(-\sum_{i=1}^{m}T[i]\),则\(Ans=t+\sum_{i=1}^{m}A[B[i]] \cdots (1)\)。

令\(cnt[i]\)为到\(i\)点的数量。

转换\((1)\)式得:\(Ans=t+\sum_{i=1}^{n}cnt[i]*A[i] \cdots(2)\)。

仔细观察\((2)\)式,我们发现,其实如果减掉了\(D[i]\)能更新的\(A[i]\)一定是连续的一段区间。

那么,我们能让答案减小的值也就是区间的长度。

注意!!!不是后缀,因为一个点的\(A[i]\)被更新到了\(L[i]\)以后,就不用对其进行更新

因为那样一定不会更优。

因此,我们只用每次找出能更新区间最长的一个\(D[i]\),将其减一。

然后,在\(O(n)\)更新所有的\(A[i]\)。

若找不到可以更新的点就直接\(break\)即可。

代码如下

#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define reg register
#define Raed Read
#define debug(x) cerr<<#x<<" = "<<x<<endl;
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a) inline int Read() {
int res = 0, f = 1;
char c;
while (c = getchar(), c < 48 || c > 57)if (c == '-')f = 0;
do res = (res << 3) + (res << 1) + (c ^ 48);
while (c = getchar(), c >= 48 && c <= 57);
return f ? res : -res;
} template<class T>inline bool Min(T &a, T const&b) {
return a > b ? a = b, 1 : 0;
}
template<class T>inline bool Max(T &a, T const&b) {
return a < b ? a = b, 1 : 0;
} const int N=2e5+5,M=2e5+5;
const int dx[4]= {1,-1,0,0},dy[4]= {0,0,1,-1}; bool MOP1; int n,m,k; struct T310 {
int A[N],a[N],b[N],D[N],t[N],L[N];
inline void solve(void) {
ret(i,1,n)D[i]=Read();
rep(i,1,m)t[i]=Raed(),a[i]=Raed(),b[i]=Raed(),Max(L[a[i]],t[i]);
rep(i,1,n)A[i]=max(A[i-1],L[i-1])+D[i-1];
int Ans=0;
rep(i,1,m)Ans+=A[b[i]]-t[i];
printf("%d\n",Ans);
}
} P10; struct T340 {
int A[N],a[N],b[N],D[N],t[N],L[N],O[N];
inline void solve(void) {
ret(i,1,n)D[i]=Read();
rep(i,1,m) {
t[i]=Raed(),a[i]=Raed(),b[i]=Raed();
Max(L[a[i]],t[i]),O[b[i]]++;
}
rep(i,1,n)A[i]=max(A[i-1],L[i-1])+D[i-1];
while(k--) {
int Sum=0,maxx=0,maxi=0;
drep(i,n,2) {
if(A[i]<=L[i])Sum=0;
Sum+=O[i];
if(D[i-1]>0&&Sum>maxx)maxx=Sum,maxi=i-1;
}
if(!maxi)break;
D[maxi]--;
rep(i,1,n)A[i]=max(A[i-1],L[i-1])+D[i-1];
}
rep(i,1,n)A[i]=max(A[i-1],L[i-1])+D[i-1];
int Ans=0;
rep(i,1,m)Ans+=A[b[i]]-t[i];
printf("%d\n",Ans);
}
} P60; bool MOP2; inline void _main(void) {
n=Read(),m=Read(),k=Raed();
if(!k)P10.solve();
else P60.solve();
} signed main() {
#define offline1
#ifdef offline
freopen("bus.in", "r", stdin);
freopen("bus.out", "w", stdout);
_main();
fclose(stdin);
fclose(stdout);
#else
_main();
#endif
return 0;
}

其实本题算法非常多。

我统计了以下几种做法:

1:陈立杰的\(O(n+m*log_n)\)的贪心做法。。

https://wenku.baidu.com/view/9c2b561d227916888486d7f2.html?from=search

2:费用流做法(第一篇题解)

https://www.luogu.org/problemnew/solution/P1315

3:\(O(n*k)\)的贪心

noip2011day2-观光公交的更多相关文章

  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. 修改 mvc webapi 默认返回 json 格式

    web api 默认的已 xml 格式返回数据 现在开发一般都是以 json 格式为主 下面配置让 webapi 默认返回 json ,在需要返回 xml 时只需要加一个查询参数 datatype=x ...

  2. CF1043F Make It One 容斥+dp+组合

    考试的时候考的一道题,感觉挺神的. 我们发现将所有数去重后最多只会选不到 $7$ 后 $gcd$ 就会变成 $1$. 令 $f[i][k]$ 表示选 $i$ 个数后 $gcd$ 为 $k$ 的方案数. ...

  3. STCubeMX软件新建Keil和IAR工程使用步骤:

    STCubeMX软件新建Keil和IAR工程使用步骤:首先是软件下载(也可在我们的百度云下载):1.STCubeMX下载地址:    http://www.stmicroelectronics.co ...

  4. Jmeter -- 添加断言,及断言结果

    步骤: 1. 添加响应断言(添加-断言-响应断言) Add -->  Assertions --> Response Assertion 2. 配置断言 判断响应内容中,是否包含关键字“禅 ...

  5. LeetCode 2. 两数相加(Add Two Numbers)

    题目描述 给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入: ...

  6. 认识一下java神器Btrace

    转载: http://calvin1978.blogcn.com/articles/btrace1.html BTrace是神器,每一个需要每天解决线上问题,但完全不用BTrace的Java工程师,都 ...

  7. C++11获取当前毫秒数

    获取当前毫秒数 主要是打印日志的时候用到 / CLOCKS_PER_SEC); 头文件为ctime

  8. Spring配置多个数据源,并实现数据源的动态切换转载)

    1.首先在config.properties文件中配置两个数据库连接的基本数据.这个省略了 2.在spring配置文件中配置这两个数据源: 数据源1 <!-- initialSize初始化时建立 ...

  9. T83310 【音乐会】二重变革

    T83310 [音乐会]二重变革 题解 你看数据那么大,又是一道数学题 题面描述这么个代码肯定不能傻fufu的直接把代码提交上去 我批评我自己 观察代码当中有一行 也就是说明最后这个数列都将变成同一个 ...

  10. 初始化EPT

    struct eptp_bits { unsigned memory_type :; /* 0: UC uncacheable, 6: WB writeback */ unsigned pagewal ...