题解【洛谷P1315】[NOIP2011]观光公交
题目描述
风景迷人的小城 Y 市,拥有 \(n\) 个美丽的景点。由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务。
观光公交车在第 \(0\) 分钟出现在 \(1\) 号景点,随后依次前往 \(2,\) \(3,\) \(\dots,\) \(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\geq0\)。
那么 ZZ 该如何安排使用加速器,才能使所有乘客的旅行时间总和最小?
输入格式
第 \(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\) 位乘客来到出发景点的时刻,出发的景点编号和到达的景点编号。
输出格式
一个整数,表示最小的总旅行时间。
输入输出样例
样例输入
3 3 2
1 4
0 1 3
1 1 2
5 2 3
样例输出
10
样例说明
对 \(D_2\) 使用 \(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 \leq n \leq 50\),\(m \leq 1000\),\(k \leq 20\),\(D_i \leq 10\),\(T_i \leq 500\);
对于 \(60\%\) 的数据,\(n \leq 100\),\(m \leq 1000\),\(k \leq 100\),\(T_i \leq 10^4\);
对于 \(100\%\) 的数据,\(n \leq 1000\),\(m \leq 10^4\),\(k \leq 10^5\),\(D_i \leq 100\),\(T_i\leq 10^5\);
noip2011提高组day2第3题
题解
贪心经典题。
很容易就可以想到,贪心策略就是每次选择人数最多的站点使用氮气加速,此处证明显然。
我们先求出没有任何氮气加速时的答案\((k=0)\),可以使用递推求解。
然后,循环\(k\)次,每次找到经过人数最多的站点,并且将到达后面的站点的时间\(-1\)。
最后统计答案输出即可。
分析一下复杂度:
循环\(k\)次,每次循环需要\(n^2\)找到人数最多的站点,复杂度为\(\mathcal{O}(k \times n^2)\),可以通过\(60 \%\)的数据点。
想办法优化。
我们注意到,每到达一个站点,公交车都会等人来了再走。
于是,我们直接在出现车等人的情况时\(\mathrm{break}\),虽然这样的时间复杂度依然是\(\mathcal{O}(k \times n^2)\),但是远远达不到这个上界,最慢的测试点只跑了\(\mathrm{311\ ms}\)。
具体实现可以参考代码。
代码
/********************************
Author: csxsl
Date: 2019/10/28
Language: C++
********************************/
#include <bits/stdc++.h>
#define itn int
#define gI gi
using namespace std;
inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return f * x;
}
inline long long gl()
{
long long f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return f * x;
}
const int maxn = 1003;
int n, m, k, d[maxn];
struct people//记录人
{
int kaishi/*到达开始站点的时间*/, chufabianhao/*出发点的编号*/, daodabianhao/*到达点的编号*/;
} a[maxn];
struct zhandian//记录每个站点
{
int daoda/*到达这个站点的时间*/, zuiwan/*最晚到达这个站点的人的时间*/, person/*要到达这个站点的人数*/;
} b[maxn];
int main()
{
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
n = gi(), m = gi(), k = gI();
for (int i = 1; i < n; i+=1) d[i] = gi();
for (int i = 1; i <= m; i+=1)
{
a[i].kaishi = gi(), a[i].chufabianhao = gi(), a[i].daodabianhao = gi();
++b[a[i].daodabianhao].person;//记录人数
b[a[i].chufabianhao].zuiwan = max(b[a[i].chufabianhao].zuiwan, a[i].kaishi);//更新最短到达这个站点的时间
}
int wudan_time = 0;//记录没有氮气加速时的用时
for (int i = 1; i <= n; i+=1)
{
b[i].daoda = wudan_time;//存储到达时间
wudan_time = max(wudan_time, b[i].zuiwan) + d[i];//进行递推
}
while (k--)//循环k次
{
int max_person = 0/*最多的人数*/, max_zhandian = 0/*最多人数的站点编号*/;
for (int i = 2; i <= n; i+=1)
{
if (!d[i - 1]) continue;//d值已经为0了,就continue,因为题目中要求d[i]>=0
int now_person = 0;//记录这个站点使用氮气加速会对多少个人造成影响
for (int j = i; j <= n; j+=1)
{
now_person += b[j].person;
if (b[j].daoda <= b[j].zuiwan) break;//出现了车等人就直接break退出
}
if (now_person > max_person)//更新答案
{
max_person = now_person;
max_zhandian = i;//进行记录
}
}
--d[max_zhandian - 1];//修改d值
for (int i = max_zhandian; i <= n; i+=1)
{
--b[i].daoda;//对之后每个站点到达的时间进行修改
if (b[i].daoda < b[i].zuiwan) break;//出现了车等人,直接退出
}
}
int ans = 0;
for (int i = 1; i <= m; i+=1)
{
ans += b[a[i].daodabianhao].daoda - a[i].kaishi;//记录答案为车到达他要到的终点的时间减去他到达开始站点的时间
}
printf("%d\n", ans);//输出
return 0;//结束
}
题解【洛谷P1315】[NOIP2011]观光公交的更多相关文章
- 【题解】洛谷P1315 [NOIP2011TG] 观光公交(前缀和+贪心)
次元传送门:洛谷P1315 思路 思路大概想到了 可是代码实现却没想到 所以参考题解了 D2T3的贪心果然有难度 我们考虑在每次用加速器有两种情况 到下一个点还需要等待:以后的时间就不再影响了 到下一 ...
- 洛谷P1315 [NOIP2011提高组Day2T3] 观光公交
P1315 观光公交 题目描述 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第 0 分钟出现在 1号 ...
- NOIP2011 观光公交 加强版
传送门 题目大意 给定从左到右的$n$个车站以及两两之间通行的需要的时间. 有$m$个人,第$i$个人会在$T_i$时刻出现在$a_i$车站,目的地是$b_i$. 一辆车第$0$时刻出现在一号站台,从 ...
- 题解 洛谷P5018【对称二叉树】(noip2018T4)
\(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...
- 题解 洛谷 P3396 【哈希冲突】(根号分治)
根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...
- 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)
题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...
- 题解-洛谷P4229 某位歌姬的故事
题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...
- 题解-洛谷P4724 【模板】三维凸包
洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...
- 题解-洛谷P4859 已经没有什么好害怕的了
洛谷P4859 已经没有什么好害怕的了 给定 \(n\) 和 \(k\),\(n\) 个糖果能量 \(a_i\) 和 \(n\) 个药片能量 \(b_i\),每个 \(a_i\) 和 \(b_i\) ...
- 题解-洛谷P5217 贫穷
洛谷P5217 贫穷 给定长度为 \(n\) 的初始文本 \(s\),有 \(m\) 个如下操作: \(\texttt{I x c}\),在第 \(x\) 个字母后面插入一个 \(c\). \(\te ...
随机推荐
- Spark学习之路 (二十)SparkSQL的元数据[转]
概述 SparkSQL 的元数据的状态有两种: 1.in_memory,用完了元数据也就丢了 2.hive , 通过hive去保存的,也就是说,hive的元数据存在哪儿,它的元数据也就存在哪儿. 换句 ...
- JAVA8对象属性的计算
Men men = new Men(); men.setName("UU"); men.setAge("56"); Men men1 = new Men(); ...
- Django上传excel表格并将数据写入数据库
前言: 最近公司领导要统计技术部门在各个业务条线花费的工时百分比,而 jira 当前的 Tempo 插件只能统计个人工时.于是就写了个报表工具,将 jira 中导出的个人工时excel表格 导入数据库 ...
- Qt 程序打包发布总结 转
1. 概述 当我们用QT写好了一个软件,要把你的程序分享出去的时候,不可能把编译的目录拷贝给别人去运行.编译好的程序应该是一个主程序,加一些资源文件,再加一些动态链接库,高大上一些的还可以做一个安装 ...
- MongoDB一些应用知识点
1.在生产环境中至少需要三个节点的复制集架构. 2.在多数的场景中WT引擎比MMAPv1更加出色. 3.要想达到极致的速度,那么一定要给MongoDB足够的内存. 4.避免使用短链接,充分利用连接池, ...
- markdwon编辑公式入门
上标与下标 上标和下标分别使用^ 与_ ,例如\(x_i^2\)表示的是:. 默认情况下,上.下标符号仅仅对下一个组起作用.一个组即单个字符或者使用{..} 包裹起来的内容.如果使用\(10^ ...
- js对象赋值
看到一道题: 根据包名,在指定空间中创建对象 效果 namespace({a: {test: 1, b: 2}}, 'a.b.c.d') 结果 {a: {test: 1, b: {c: {d: {}} ...
- ST表求区间最值
#include<bits/stdc++.h> #define ll long long #define lowbit(x) x&-x using namespace std; ; ...
- 数据预处理 | 使用 pandas.to_datetime 处理时间类型的数据
数据中包含日期.时间类型的数据可以通过 pandas 的 to_datetime 转换成 datetime 类型,方便提取各种时间信息 1 将 object 类型数据转成 datetime64 1&g ...
- Ionic 使用 NFC
Ionic 使用 NFC 哎哟喂,因为项目需要使用 Ionic 调用手机 NFC 功能,踩了好多坑,真的是,不过终于不负众望拿到了id.现在就记录一下我的步骤和踩过的坑! 步骤 我装的Ionic可能是 ...