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

相关推荐
lvwangshu15 小时前
P7668 [JOI 2018 Final] 团子制作 / Dango Maker 题解
动态规划·题解·贪心·性质题·思维好题
_Twink1e18 小时前
openJiuwen 实训营 Day 1 · WorkSwarm 入门教程
开发语言·c++·openjiuwen
dong_junshuai19 小时前
每天一个开源项目#87 fmt:24.5K Stars 的 C++ 格式化核心
c++·开源·github
雪的季节19 小时前
Multisim14.0的详细中文安装步骤【附安装包】
c++
Persistent的粽子!20 小时前
C++:类与对象(二)
开发语言·c++
蒸蒸yyyyzwd21 小时前
cpp 选手备战秋招学习笔记 day23
c++·求职招聘
.YM.Z21 小时前
C++ STL 容器深度剖析:vector 与 list 的模拟实现及对比
开发语言·c++·vector·list
mengzhi啊1 天前
QEventLoop loop配合loop.exec();替代while(1)。电脑cpu占用为0,使用while(1)cpu占用率100%
c++·qt
HugoStudio_SWAN1 天前
洛谷 P1319 / P1320 压缩技术——同一枚硬币的正反面
c++·学习·程序人生·算法
小小晓.1 天前
C++单例模式万字详解:6种实现演进+线程安全彻底解决+CRTP终极模板
c++·单例模式