正在载入在线练习界面,本页内容可直接阅读…

AK CSP › NOIP 提高 2015 第一轮真题 › 第 29 题

NOIP 提高 2015 第一轮 第 29 题:完善程序(双子序列最大和)第 3 空

完善程序 · 动态规划 · 答案 rmax[i]=rmax[i+1]+x[i]

题目

(双子序列最大和)给定一个长度为 $n(3 \leq n \leq 1000)$ 的整数序列,要求从中选出两个连续子序列,使得这两个连续子序列的序列和之和最大,最终只需输出这个最大和。一个连续子序列的序列和为该连续子序列中所有数之和。要求:每个连续子序列长度至少为 $1$,且两个连续子序列之间至少间隔 $1$ 个数。(第五空 $4$ 分,其余 $2.5$ 分)

#include <iostream>
using namespace std;
const int MAXN = 1000;
int n, i, ans, sum;
int x[MAXN];
int lmax[MAXN]; // lmax[i]为仅含 x[i]及 x[i]左侧整数的连续子序列的序列和中,最大的序列和
int rmax[MAXN]; // rmax[i]为仅含 x[i]及 x[i]右侧整数的连续子序列的序列和中,最大的序列和
int main() {
    cin >> n;
    for (i = 0; i < n; i++)
        cin >> x[i];
    lmax[0] = x[0];
    for (i = 1; i < n; i++)
        if (lmax[i - 1] <= 0)
            lmax[i] = x[i];
        else
            lmax[i] = lmax[i - 1] + x[i];
    for (i = 1; i < n; i++)
        if (lmax[i] < lmax[i - 1])
            lmax[i] = lmax[i - 1];
        (1)    ;
    for (i = n - 2; i >= 0; i--)
        if (rmax[i + 1] <= 0)
                (2)    ;
        else
                (3)    ;
    for (i = n - 2; i >= 0; i--)
        if (rmax[i] < rmax[i + 1])
                (4)    ;
    ans = x[0] + x[2];
    for (i = 1; i < n - 1; i++) {
        sum =     (5)    ;
        if (sum > ans)
            ans = sum;
    }
    cout << ans << endl;
    return 0;
}

本小题

第 3 空应填( )

答案

rmax[i]=rmax[i+1]+x[i]

题解

考点定位

本题(双子序列第③空)考「右侧递推延伸」,对应大纲 4.3.2 DP(难度【3】)。

解题过程

③处前缀和 >0 时延伸:

``cpp rmax[i] = rmax[i+1] + x[i]; ``

答案:rmax[i]=rmax[i+1]+x[i]。

易错提醒

① 与②构成 if/else 两分支;② 此处 rmax 是「以 i 开头的最大段和」原始值。

真题版权归 CCF 所有,本站仅用于非商业教学用途。页面加载后可直接在线作答,作答记录保存在本浏览器或账号中。 京ICP备2026056990号-1 京公网安备11010502062986号