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
状态转移

相关推荐
有点。2 小时前
C++倍增法(练习题)
c++·算法
凡人叶枫2 小时前
Effective C++ 条款23:宁以 non-member、non-friend 替换 member 函数
linux·开发语言·c++·嵌入式开发
C语言小火车2 小时前
什么时候用智能指针?什么时候用裸指针?
c语言·c++·学习·指针
玖玥拾3 小时前
C/C++ 基础笔记(十二)友元、运算符重载
c语言·c++·运算符重载·友元
智者知已应修善业3 小时前
【51单片机8位数码管同时倒计时从9999】2024-1-25
c++·经验分享·笔记·算法·51单片机
渡之3 小时前
GRiM-Net 深度解析 | 无人机 GNSS 拒止场景下两阶段跨视角视觉定位框架
深度学习·算法·动态规划·无人机
郝学胜_神的一滴4 小时前
Qt 高级开发 031:QListWidget图标布局实战
c++·qt
Coder-magician5 小时前
《代码随想录》刷题打卡day15:二叉树part05
数据结构·c++·算法
Irissgwe5 小时前
算法的时间复杂度和空间复杂度
数据结构·c++·算法·c·时间复杂度·空间复杂度