洛谷 P1115:最大子段和 ← 动态规划+优先队列
2026/7/28 14:50:05 网站建设 项目流程

【题目来源】
https://www.luogu.com.cn/problem/P1115

【题目描述】
给出一个长度为 n 的序列 a,选出其中
连续且非空的一段使得这段和最大。

【输入格式】
第一行是一个整数,表示序列的长度 n。
第二行有 n 个整数,第 i 个整数表示序列的第 i 个数字 ai。

【输出格式】
输出一行一个整数表示答案。

【输入样例】
7
2 -4
3 -1 2-4 3

【输出样例】
4

【样例说明】
选取 [3,5] 子段 {3,−1,2},其和为 4。

【数据规模与约定】
对于 40% 的数据,保证 n≤2×10^3。
对于 100% 的数据,保证1≤n≤
2×10^5,-10^4≤ai≤10^4

【算法分析】
● 子序列问题是指在一个序列(如数组、字符串等)中,寻找满足特定条件的子序列的算法问题。子序列指的是从原序列中
依序选取的元素组成的新序列,但选取的元素不一定连续
● 子序列问题求解的核心思路:通过分解子问题,利用
动态规划特殊数据结构进行优化。不同变体需要灵活调整状态定义和转移条件‌。
● 动态规划定义
状态定义‌:
dp[i] 表示以第 i 个元素结尾的连续子数组的最大和‌
‌目标‌:通过比较「当前元素单独成段」和「接上前面子段」两种情况,逐步递推全局最大值‌。

【算法代码:
朴素写法

#include <bits/stdc++.h> using namespace std; const int maxn=2e5+5; int a[maxn],dp[maxn]; int ans=INT_MIN; int n; int main() { cin>>n; for(int i=1; i<=n; i++) cin>>a[i]; for(int i=1; i<=n; i++) { dp[i]=max(a[i],dp[i-1]+a[i]); } for(int i=1; i<=n; i++) { ans=max(ans,dp[i]); } cout<<ans<<endl; return 0; } /* in: 7 2 -4 3 -1 2 -4 3 out: 4 */


【算法代码:优先队列

#include <bits/stdc++.h> using namespace std; const int maxn=2e5+5; int a[maxn],dp[maxn]; priority_queue<int> Q; int n; int main() { cin>>n; for(int i=1; i<=n; i++) cin>>a[i]; for(int i=1; i<=n; i++) { dp[i]=max(a[i],dp[i-1]+a[i]); Q.push(dp[i]); } cout<<Q.top(); return 0; } /* in: 7 2 -4 3 -1 2 -4 3 out: 4 */



【参考文献】
https://www.luogu.com.cn/problem/solution/P1115
https://www.cnblogs.com/zwfymqz/p/6809398.html





需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询