GESP2026年3月认证C++六级真题与解析(编程题1 选数)



这道题真正考的是:

动态规划(DP)


而且是非常经典的:

线性DP + 跳跃转移


一、题目讲了什么?

1、题目给了两个数组:

复制代码
a[]
b[]

2、例如样例:

复制代码
a:
1 2 3 4

b:
3 3 1 1

3、题目允许我们选择一些位置。

(1)假如选了位置 i:

获得:

复制代码
a[i]

分数。


(2)但是代价是:

会跳过后面若干位置。


(3)跳过多少?

由:

复制代码
b[i]

决定。


二、故事理解

1、想象有一条糖果街。

复制代码
位置:

1  2  3  4

糖果:

1  2  3  4

2、每个位置还有一个魔法数字:

复制代码
3 3 1 1

3、如果你站在第1格:

复制代码
糖果=1
跳跃=3

拿走糖果后:

复制代码
获得1分

然后必须跳到:

复制代码
1+3=4

位置。


4、如果站在第2格:

复制代码
获得2分

然后跳到:

复制代码
2+3=5

超出范围。


5、目标:

复制代码
获得最多糖果

三、DP状态定义

1、定义:

复制代码
f[i]

表示:

到达位置 i 时,之前已经获得的最大分数。


2、比如:

复制代码
f[4]=10

意思:

复制代码
来到4号位置前
已经赚了10分

3、注意:

还没拿4号位置的糖果。


四、两种选择

来到 i。

有两种情况。


选择1:拿糖果

获得:

复制代码
a[i]

分。


然后跳到:

复制代码
i+b[i]

位置。

于是:

复制代码
f[i+b[i]]
=
max(
    f[i+b[i]],
    f[i]+a[i]
)

意思:

复制代码
把当前糖果拿走
然后跳过去

选择2:不拿糖果

直接走到下一格。

复制代码
f[i+1]
=
max(
    f[i+1],
    f[i]
)

意思:

复制代码
这格不要
继续往前

五、手算样例

1、样例:

复制代码
4

a:
1 2 3 4

b:
3 3 1 1

2、初始:

复制代码
f:

0 0 0 0

(1)i=1

拿:

复制代码
得1分

跳:

复制代码
1+3=4

所以:

复制代码
f[4]=1

不拿:

复制代码
f[2]=0

现在:

复制代码
f:

0 0 0 1

(2)i=2

拿:

复制代码
2+3=5

越界。

不能。


不拿:

复制代码
f[3]=0

(3)i=3

拿:

复制代码
得3分

跳:

复制代码
3+1=4

于是:

复制代码
f[4]
=max(1,3)
=3

(4)i=4

已有:

复制代码
f[4]=3

拿:

复制代码
3+4
=
7

(5)答案:

复制代码
7

六、为什么不是贪心

很多同学会想:

复制代码
每次选最大的糖果

例如:

复制代码
10 1 1 100

可能:

复制代码
拿10

后面就跳飞了。

失去:

复制代码
100

因此:

局部最优

全局最优


所以必须DP。


七、参考代码

官方代码:

复制代码
#include <cstdio>
#include <algorithm>
using namespace std;

const int N = 100005;

int n;
int a[N];
int b[N];

long long f[N];
long long ans;

int main()
{
    scanf("%d",&n);

    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);

    for(int i=1;i<=n;i++)
        scanf("%d",&b[i]);

    for(int i=1;i<=n;i++)
    {
        ans=max(ans,f[i]+a[i]);

        // 选当前位置
        if(i+b[i]<=n)
        {
            f[i+b[i]]
            =
            max(
                f[i+b[i]],
                f[i]+a[i]
            );
        }

        // 不选当前位置
        f[i+1]
        =
        max(
            f[i+1],
            f[i]
        );
    }

    printf("%lld\n",ans);

    return 0;
}

八、本题考点

1、本题经典模型:

复制代码
走到位置 i
↓
做决策
↓
跳到新位置
↓
继续DP

2、结构:

复制代码
dp[下一状态]
=
max(
    dp[下一状态],
    dp[当前状态]+收益
);

九、记忆口诀

1、看到:

复制代码
一条线
从左到右

每个位置有收益

选择后跳到新位置

求最大收益

2、立刻想到:

复制代码
线性DP
状态转移

相关推荐
apocelipes1 天前
常用编程语言和库的正则表达式性能对比
c语言·c++·python·性能优化·golang·开发工具和环境
郝学胜_神的一滴3 天前
CMake 034:生成器表达式:解耦构建时序、精简分支逻辑的终极利器
c++·cmake
见过夏天3 天前
C++ 基础入门完全指南
c++
用户805533698035 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
BadBadBad__AK5 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境6 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境6 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴7 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
卷无止境9 天前
C++ 的Eigen 库全解析
c++
卷无止境9 天前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端