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

相关推荐
码客-ygluu1 小时前
一个通用游戏数据服务器
c++·架构
another heaven1 小时前
【C/C++ Ranges 是零开销抽象吗?拆开管道、惰性求值和编译期膨胀】
c语言·开发语言·c++
上海潭龙东海科技有限公司1 小时前
客运站管控之动态孪生技术方案(新增一屏管控模块
数据仓库·人工智能·算法·重构·动态规划
YLCHUP3 小时前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
xiaoye-duck4 小时前
《C++ 项目:手写大模型接入 SDK》会话模块整合:内存 SessionManager 与 DataManager 持久化联动
开发语言·数据库·c++·语言模型
思麟呀4 小时前
背包DP(01背包+完全背包)
c++·算法
旖旎夜光5 小时前
【C++ 基础入门】C++11 新特性(中):右值引用、移动语义与完美转发
开发语言·c++·笔记·学习
ShineWinsu6 小时前
对于Qt:QTabWidget常见属性的解析
开发语言·数据库·c++·qt·浏览器·qtabwidget·标签页
俊俊几年的7 小时前
动态规划(Dynamic Programming)详解:从入门到 LeetCode Hot 100
linux·c++·算法·leetcode·嵌入式·动态规划·c
老歌老听老掉牙1 天前
案例 7:二维 Rosenbrock 函数最小值(香蕉函数)
c++·pso