1 条题解
-
0
#include<bits/stdc++.h> using namespace std; int n; // [1] n-输入的整数序列长度 int arr[100100]; // [2] arr数组-存储输入的整数序列(下标从1开始) long long dp_l[100100]; // [3] dp_l[i]-初始定义:以i结尾的最大连续子段和;后续转换为:arr[1..i]区间内的最大子段和(前缀最大值) long long dp_r[100100]; // [4] dp_r[i]-初始定义:以i开始的最大连续子段和;后续转换为:arr[i..n]区间内的最大子段和(后缀最大值) int main(){ cin>>n; // [5] 读取序列长度n for(int i=1;i<=n;i++) cin>>arr[i]; // [6] 读取n个整数存入arr数组(下标从1开始,方便边界处理) // ========== 第一步:计算从左到右的「以i结尾的最大子段和」 ========== dp_l[0] = 0; // [7] 边界初始化:前0个元素的子段和为0 for(int i=1;i<=n;i++){ // 状态转移:以i结尾的子段,要么仅包含当前元素arr[i],要么包含前面的子段并加上arr[i] dp_l[i] = max((long long)arr[i], dp_l[i-1]+arr[i]); } // ========== 第二步:计算从右到左的「以i开始的最大子段和」 ========== dp_r[n+1] = 0; // [8] 边界初始化:第n+1个元素的子段和为0 for(int i=n;i>=1;i--){ // 状态转移:以i开始的子段,要么仅包含当前元素arr[i],要么包含后面的子段并加上arr[i] dp_r[i] = max((long long)arr[i], dp_r[i+1]+arr[i]); } // ========== 第三步:将dp_l转换为「前缀最大值数组」 ========== // 转换后dp_l[i]表示arr[1..i]区间内的最大子段和(即左边到i为止的最优子段) for(int i=2;i<=n;i++){ dp_l[i] = max(dp_l[i], dp_l[i-1]); } // ========== 第四步:将dp_r转换为「后缀最大值数组」 ========== // 转换后dp_r[i]表示arr[i..n]区间内的最大子段和(即右边从i开始的最优子段) for(int i=n-1;i>=1;i--){ dp_r[i] = max(dp_r[i], dp_r[i+1]); } // ========== 第五步:遍历分割点,计算两个不相交区间的最大和 ========== long long max_sum = -1e18; // [9] 初始化最大和为极小值(处理负数情况) for(int i=1;i<n;i++){ // 分割点为i,左边取arr[1..i]的最大子段(dp_l[i]),右边取arr[i+1..n]的最大子段(dp_r[i+1]) max_sum = max(max_sum, dp_l[i] + dp_r[i+1]); } cout<<max_sum; // [10] 输出两个不相交连续区间的最大和 return 0; }
- 1
信息
- ID
- 1325
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者