\(Meaning\)

\(Solution\)

这道题我来讲一个不一样的解法:\(dp\)

在写 \(dp\) 之前,我们需要明确以下几个东西:状态的表示,状态转移方程,边界条件和答案的表示。

状态的表示

\(dp[i]\) 表示到达第 \(i\) 个站点所需要的最少钱数, \(w[i]\) 表示在使用最少钱数到达第 \(i\) 个站点时多余的路程。

状态转移方程

\[
dp[i]=dp[i-1]+\bigg\lceil\frac{v[i-1]-w[i-1]}{d}\bigg\rceil\times pre\_min(i-1)

\]

\[
w[i]=\bigg\lceil\frac{v[i-1]-w[i-1]}{d}\bigg\rceil-v[i-1]+w[i-1]

\]

其中 \(pre\_min(i)\) 表示前 \(i\) 个站点中最小的油价。

边界条件

\[
dp[i]=0,w[i]=0

\]

答案的表示

\[
dp[n]

\]

问题

在状态转移方程中,怎样在 \(O(1)\) 的时间复杂度下完成 \(pre\_min\) 函数呢?

这就涉及到了一个算法:

\(ST\) 表

在算法和数据结构中,ST表(Sparse Table)是一种用于解决区间查询问题的数据结构。它可以有效地回答各种形式的查询,例如最小值、最大值、区间和等。

简介

ST表的主要思想是通过预处理来加速区间查询。它使用倍增 DP 的思想将一个数组分割成多个子区间,并在每个子区间上计算出某种操作的结果。然后,根据这些预先计算好的结果,我们可以根据需要合并区间来回答各种查询。

具体的实现过程如下:

  1. 初始化ST表,ST表是一个二维数组。
  2. 将输入的原始数组填充到ST表的第一行。
  3. 使用递推关系填充ST表的其他行,直到得到完整的ST表。
  4. 根据查询的起始位置和区间长度,在ST表中找到对应区间的值,结合适当的操作得出最终结果。

查询操作

对于任何查询操作,我们可以使用以下步骤来回答:

  1. 计算出查询区间的长度len。

  2. 找到大于等于len的最大值j,使得2^j <= len。

  3. 使用预处理的结果和递推关系,在ST表中找到对应的值,并结合适当的操作得到查询结果。

这种方法的时间复杂度为O(1),因为我们只需进行几次常数级别的操作即可回答查询。

应用场景

ST表在解决各种区间查询问题时非常有用。以下是一些常见的应用场景:

  • 查询最小值/最大值:通过选择适当的查询操作,在O(1)的时间复杂度内回答每个查询。
  • 区间和查询:可以通过使用累积和来实现区间和查询。
  • 区间gcd查询:可以通过预处理和递推关系计算区间内的最大公约数。

总结

ST表是一种高效解决区间查询问题的数据结构。通过预先计算和递推关系,我们可以在O(1)的时间复杂度内回答各种形式的查询。它的实现相对简单且灵活,适用于多种应用场景。

模板

初始化(时间复杂度 \(O(\log_2n)\) )

for(int i=1;i<=n;i++) {
st[i][0]=a[i];
}
for(int j=1;(1<<j)<=n;j++) {
for(int i=1;i+(1<<j)-1<=n;i++) {
st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}

查询(时间复杂度 \(O(1)\) )

l=1,r=i-1,len=log2(r-l+1);
pm=min(st[l][len],st[r-(1<<len)+1][len]);

解决问题

有了ST表,我们就可以在O(1)的时间复杂度中查询最值了,那我们程序的最终问题:TLE也解决了。程序整体时间复杂度为O(n),可以通过此题。

AC代码如下。

\(Accept\ Code\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e5+5;
ll v[N],a[N],w[N],dp[N],st[N][20];
ll n,d,l,r,len,pm;
int main() {
cin>>n>>d;
for(int i=1;i<n;i++) {
cin>>v[i];
}
for(int i=1;i<=n;i++) {
cin>>a[i];
}
for(int i=1;i<=n;i++) {
st[i][0]=a[i];
}
for(int j=1;(1<<j)<=n;j++) {
for(int i=1;i+(1<<j)-1<=n;i++) {
st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
for(int i=2;i<=n;i++) {
l=1,r=i-1,len=log2(r-l+1);
pm=min(st[l][len],st[r-(1<<len)+1][len]);
dp[i]=dp[i-1]+ceil(1.0*(v[i-1]-w[i-1])/d)*pm;
w[i]=ceil(1.0*(v[i-1]-w[i-1])/d)*d-(v[i-1]-w[i-1]);
}
cout<<dp[n];
return 0;
}

【题解】P9749 [CSP-J 2023] 公路的更多相关文章

  1. CSP J/S 初赛总结

    CSP J/S 初赛总结 2021/9/19 19:29 用官方答案估计 J 涂卡的时候唯一的一支 2B 铅笔坏了,只能用笔芯一个个涂 选择 \(-6\ pts\) 判断 \(-3\ pts\) 回答 ...

  2. 2019 CSP J/S第2轮 视频与题解

    CSP入门组和提高组第二轮题解 转自网络

  3. 【游记】CSP J/S 2019 游记

    J 组 \(2:30\)开始, \(2:13\)还在酒店的我看了看手表...飞奔考场. T1 数字游戏 秒切. 下午某中学某大佬说可用线性基(%) T2 公交换乘 用单调队列思想,秒切. T3 纪念品 ...

  4. CSP J/S 2019受虐记

    一枚蒟蒻的游记~ 提高组DAY1 不是说每场考试都有一道签到题吗 那我tm读了三遍题硬是没找到一道水题是怎么回事(是我太弱了吗) 没办法,硬着头皮做T1 暴力写法...期望得分30pts 于是...在 ...

  5. 【题解】 [HNOI/AHOI2018]道路 (动态规划)

    懒得复制,戳我戳我 Solution: \(dp[i][j][k]\)以\(i\)为子树根节点,到根节点中有\(j\)条公路没修,\(k\)条铁路没修,存子树不便利和 \(dp[i][j][k]=mi ...

  6. 【codeforces】【比赛题解】#855 Codefest 17

    神秘比赛,以<哈利波特>为主题……有点难. C题我熬夜切终于是写出来了,可惜比赛结束了,气啊. 比赛链接:点我. [A]汤姆·里德尔的日记 题意: 哈利波特正在摧毁神秘人的分灵体(魂器). ...

  7. [游记]2020/CSP - S总结

    2020 / C S P − S 总 结 2020/CSP - S总结 2020/CSP−S总结 这年的 C S P CSP CSP考的不是很理想,本来稳进的 C S P − J CSP-J CSP− ...

  8. Atcoder 2159 連結 / Connectivity(并查集+map乱搞)

    問題文N 個の都市があり.K 本の道路と L 本の鉄道が都市の間に伸びています. i 番目の道路は pi 番目と qi 番目の都市を双方向に結び. i 番目の鉄道は ri 番目と si 番目の都市を双 ...

  9. 洛谷 P1373 小a和uim之大逃离 Label:dp 不会

    题目背景 小a和uim来到雨林中探险.突然一阵北风吹来,一片乌云从北部天边急涌过来,还伴着一道道闪电,一阵阵雷声.刹那间,狂风大作,乌云布满了天空,紧接着豆大的雨点从天空中打落下来,只见前方出现了一个 ...

  10. 【CodeForces 261B】Maxim and Restaurant(DP,期望)

    题目链接 第一种解法是$O(n^3*p)$的:f[i][j][k]表示前i个人进j个人长度为k有几种方案(排列固定为123..n时).$f[i][j][k]=f[i-1][j][k]+f[i-1][j ...

随机推荐

  1. 记一次github上传文件夹(项目)的历程和踩坑

    1.git官网登录自己的git账号(没有就自己注册一个):https://github.com/  2.首先是下载安装好git软件:https://gitforwindows.org/ (1)这里要注 ...

  2. nginx安装 没有网络且缺少基础包的环境下

    一.安装 [root@oracle ~]# cd /etc/yum.repos.d/ [root@oracle yum.repos.d]# rm -rf * [root@oracle yum.repo ...

  3. 四、mycat垂直分库

    系列导航 一.Mycat实战---为什么要用mycat 二.Mycat安装 三.mycat实验数据 四.mycat垂直分库 五.mycat水平分库 六.mycat全局自增 七.mycat-ER分片 一 ...

  4. 【调试】GDB使用总结

    启动 在shell下敲gdb命令即可启动gdb,启动后会显示下述信息,出现gdb提示符. ➜ example gdb GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1 Cop ...

  5. C语言基础之基础的输入输出

    前言 学一门编程语言,不能编写让用户输入数据然后输出处理后的数据的程序那么就等于没学,而在C语言中可以用printf() 和 scanf() 函数进行输入和输出操作.这两个函数是内置的库函数,定义在 ...

  6. 线性代数 · 矩阵 · Matlab | Moore-Penrose 伪逆矩阵代码实现

    背景 - Moore-Penrose 伪逆矩阵: 对任意矩阵 \(A\in\mathbb C^{m\times n}\) ,其 Moore-Penrose 逆矩阵 \(A^+\in\mathbb C^ ...

  7. Mysql 中 not in 的查询优化

    本文为博主原创,转载请注明出处: 最近做性能优化时,通过开启 MySQL 的慢日志查询配置,发现 有一条慢sql,在这里记录下分析和优化的过程. 该慢 sql 如下: select id from f ...

  8. 使用pip安装pycharm插件时,要使用管理员权限打开cmd安装

    1.问题 安装到一半报错 报错1 报错2 2.解决 解决1 原文:https://blog.csdn.net/weixin_44899752/article/details/128372969 下面是 ...

  9. [转帖]KingbaseES 事务总结

    目录 1. 什么是事务? 2. 事务的属性-ACID 3. 数据库事务的操作方式 3.1. SET TRANSACTION 3.2. BEGIN 3.3. COMMIT 3.4. ROLLBACK 3 ...

  10. [转帖]如何理解 iowait

    Linux中,%iowait 过高可能是个问题,严重的时候,它能使服务停止, 但问题是,多高才算高? 什么时候应该担心呢? 本文将讨论 iowait 的含义.相关的统计数据.原理以及 iowait的瓶 ...