题解:最大子段和3

【题目描述】

皮皮刚刚学完最大子段和,老师为了检测皮皮是否真正掌握,决定对它进行提问。

给出数组 \(a\) 的元素 \(a[1],a[2],⋯ ,a[n]\) 的值,给定一个 \(1\) ~ \(n\) 之间的位置 \(pos\),请问 \(a[pos]\)~\(a[n]\) 之间的最大子段和是多少?请回答 \(m\) 个这样的问题。

【输入】

\(1\) 行,是两个正整数 \(n\)\(m\),分别表示数组 \(a\) 的长度和询问的次数。

\(2\) 行,用空格隔开的 \(n\) 个整数,依次是 \(a[1],a[2],⋯ ,a[n]\) 的值。

接下来的 \(m\) 行,每行一个正整数 \(pos\),表示询问的位置。

【输出】

\(m\) 行,每行一个整数,为所求的最大子段和.

【输入样例】

6 1
1 -6 5 -4 2 4
6

【输出样例】

4

【代码详解】

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

#define int long long
const int N = 100005;
int n, a[N], dp[N], pos, maxn = -1e9, m;  // n: 数组长度,a: 数组元素,dp: 动态规划数组,pos: 查询位置,m: 查询次数

signed main()
{
    cin >> n >> m;  // 读入数组长度和查询次数
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];  // 读入数组元素
    }
    
    // 从后向前计算最大子段和
    // dp[i]表示以a[i]开头的最大子段和
    for (int i = n; i >= 1; i--)
    {
        dp[i] = max(dp[i + 1] + a[i], a[i]);  // 要么从当前位置开始,要么加上后面的
    }
    
    // 从后向前处理,dp[i]表示从i到n的最大子段和
    for (int i = n - 1; i >= 1; i--)
    {
        dp[i] = max(dp[i + 1], dp[i]);  // 更新为从i到n的最大子段和
    }
    
    // 调试输出
    // for (int i=1;i<=n;i++)
    // 	cout<<dp[i]<<' ';
    // cout<<endl;
    
    // 处理查询
    while (m--)
    {
        cin >> pos;  // 读入查询位置
        cout << dp[pos] << endl;  // 输出从pos位置开始到结尾的最大子段和
    }
    return 0;
}

【运行结果】

6 1
1 -6 5 -4 2 4
6
4
posted @ 2026-02-21 15:13  团爸讲算法  阅读(1)  评论(0)    收藏  举报