线性DP例题—破损的楼梯

破损的楼梯
问题描述
小蓝来到了一座高耸的楼梯前,楼梯共有N级台阶,从第0级台阶出发。小蓝每次可以迈上1级或2级台阶。但是,楼梯上的第a1级、第a₂级、第ag级,以此类推,共M级台阶的台阶面已经坏了,不能踩上去。
现在,小蓝想要到达楼梯的顶端,也就是第N级台阶,但他不能踩到坏了的台阶上。请问他有多少种不踩坏了的台阶到达顶端的方案数?
由于方案数很大,请输出其对10°+7取模的结果。
输入格式
第一行包含两个正整数N(1≤N≤10⁵)和M(O≤M≤N),表示楼梯的总级数和坏了的台阶数。
接下来一行,包含M个正整数a1,a2,...,am(1≤al<a2<
a3<am≤N),表示坏掉的台阶的编号。
输出格式
输出一个整数,表示小蓝到达楼梯顶端的方案数,对10⁹+7取模。
样例输入
61
3
样例输出
4
运行限制
语言
最大运行时间
C++
1s
C
1s
Java
2s
Python3
3s
最大运行内存
256M
256M
256M
256M

我的答案:

一、信息

  • 楼梯总级数:N
  • 坏了的台阶数:M
  • 坏了的台阶编号:a1, a2, ..., am
  • 小蓝每次可以迈上:1级或2级台阶
  • 目标:计算小蓝不踩坏了的台阶到达顶端的方案数,并对10⁹+7取模

二、分析

  • 信息作用
    • 楼梯总级数N决定了小蓝需要达到的目标高度。
    • 坏了的台阶数M和坏了的台阶编号决定了小蓝不能走的台阶。
    • 小蓝每次可以迈上1级或2级台阶,决定了他每一步的可能性。
  • 思考过程
    • 问题可以转化为动态规划问题,每到达一个台阶的方案数依赖于之前的状态。
    • 对于每一级台阶i,其方案数可由前一级台阶i-1和前两级台阶i-2的方案数累加得到,除非该级台阶坏了。
  • 分析过程
    • 定义一个数组dp,其中dp[i]表示到达第i级台阶的方案数。
    • 初始化dp[0] = 1(站在地面上只有一种方式),对于第1级台阶,如果它不是坏的,那么dp[1] = 1。
    • 从第2级台阶开始遍历到N级台阶,如果当前台阶i没坏,那么dp[i] = dp[i-1] + dp[i-2]。
    • 最后输出dp[N]对10⁹+7取模的结果。

三、算法设计

  • 初始化一个长度为N+1的数组dp,所有元素为0。
  • 设置dp[0] = 1,表示在开始位置的方案数。
  • 遍历每一级台阶i从1到N:
    • 如果台阶i没有坏,更新dp[i] = (dp[i-1] + (i >= 2 ? dp[i-2] : 0)) % (10⁹+7)。
  • 输出dp[N]。

四、代码实现

#include <iostream>
#include <vector>
using namespace std;

const int MOD = 1e9 + 7;

int main() {
    int N, M;
    cin >> N >> M;
    vector<bool> bad(N + 1, false); // 标记坏的台阶
    for (int i = 0; i < M; ++i) {
        int a;
        cin >> a;
        bad[a] = true;
    }

    vector<int> dp(N + 1, 0);
    dp[0] = 1; // 在地面,只有一种方式
    for (int i = 1; i <= N; ++i) {
        if (!bad[i]) {
            dp[i] = dp[i - 1] + (i >= 2 ? dp[i - 2] : 0);
            dp[i] %= MOD;
        }
    }

    cout << dp[N] << endl;
    return 0;
}

五、实现代码过程中可能遇到的问题

  • 数组越界:需要确保在访问dp数组时,索引是有效的,特别是当i-2可能小于0时。
  • 模运算性质:在进行加法操作后立即取模,以避免整数溢出。
  • 初始化问题:确保所有dp数组元素初始化为0,坏的台阶对应的dp值保持为0。
  • 逻辑错误:在处理坏掉的台阶时,确保不会更新其dp值,因为不能踩上去。

正确答案:

源代码: 

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10 , mod = 1e9 + 7;
int n , m , x , f[N] , vis[N];
signed main(){
    cin >> n >> m;
    for(int i = 1 ; i <= m ; i ++) {
        cin >> x;
        vis[x] = 1;
    }
    f[0] = 1;
    for(int i = 1 ; i <= n ; i ++){
        if(vis[i]) continue ;
        f[i] = f[i - 1] + f[i - 2];
        f[i] %= mod;
    }
    cout << f[n] << '\n';
    return 0;
}

 

  • 21
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏驰和徐策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值