0%

P16230 [蓝桥杯 2026 省 A] 综合应变指标(把绝对值变为 分类讨论,去掉绝对值,然后我们会发现好处理很多)

题目大意

P16230 [蓝桥杯 2026 省 A] 综合应变指标

题目描述

航空引擎涡轮叶片是确保国家空天安全的核心装备,其制造工艺代表了工业技术的巅峰。

这天,在精密检测实验室的中央,首席结构分析师小蓝正利用高精度传感器,沿涡轮叶片的中轴线进行连续扫描。扫描产生的反馈数据被转化为一条包含 NN 个元素的序列 A=(A1,A2,,AN)A = (A_1, A_2, \dots, A_N)

为了评估叶片在极限运行负载下的稳定性,小蓝需要针对这组序列计算出一个综合应变指标。计算该指标的第一步是选定三个分割点 i,j,ki, j, k(满足 1i<j<k<N1 \le i < j < k < N),将整条序列划分为以下四个连续且非空的子段:

  1. 第一段:A1,,AiA_1, \dots, A_i

  2. 第二段:Ai+1,,AjA_{i+1}, \dots, A_j

  3. 第三段:Aj+1,,AkA_{j+1}, \dots, A_k

  4. 第四段:Ak+1,,ANA_{k+1}, \dots, A_N

第二步,需要计算每一个子段内所有数值的总和,并取其绝对值。这四个绝对值的累加总和被定义为该划分方案下的综合应变指标:

A1++Ai+Ai+1++Aj+Aj+1++Ak+Ak+1++AN |A_1 + \cdots + A_i| + |A_{i+1} + \cdots + A_j| + |A_{j+1} + \cdots + A_k| + |A_{k+1} + \cdots + A_N|

分割点的选择有多种可能,不同的方案会导致不同的指标结果。

现在,请你帮助小蓝找出一种划分方案,使得得到的综合应变指标的数值最大。

输入格式

第一行包含一个正整数 NN,表示扫描序列采集到的反馈节点总数。

第二行包含 NN 个整数 A1,A2,,ANA_1, A_2, \dots, A_N,表示序列的元素。

输出格式

输出一行一个整数,表示序列所能达到的最大综合应变指标。

输入输出样例 #1

输入 #1

1
2
5
1 -1 -2 3 5

输出 #1

1
12

说明/提示

【评测用例规模与约定】

对于 30%30\% 的评测用例,4N1004 \le N \le 100

对于 60%60\% 的评测用例,4N4004 \le N \le 400

对于所有评测用例,4N1054 \le N \le 10^5109Ai109-10^9 \le A_i \le 10^9

思路讲解

PDF

image

写出一个 O(n2)O(n^2) 的 dp 代码没有那么难。

1
2
3
4
5
6
7
void excute_dp(const vector<ll> &dp1, vector<ll> &dp2) {
for (int i = 1; i <= N; ++i) {
for (int j = 1; j <= i; ++j) {
dp2[i] = max(dp2[i], dp1[j] + abs(preA[i] - preA[j]));
}
}
}

现在最关键的就是如何把这个内层的 for 循环给优化掉。

有绝对值?那就要把绝对值去掉,用分类讨论。

说白了,其实就是这样子,因为我们有 max 函数,甚至可以不需要分类讨论。

1
2
3
4
5
6
7
8
void excute_dp(const vector<ll> &dp1, vector<ll> &dp2) {
for (int i = 1; i <= N; ++i) {
for (int j = 1; j <= i; ++j) {
dp2[i] = max(dp2[i], dp1[j] + preA[i] - preA[j]);
dp2[i] = max(dp2[i], dp1[j] - (preA[i] - preA[j]));
}
}
}

AC代码

AC
https://www.luogu.com.cn/record/273684075

心路历程(WA,TLE,MLE……)