蓝桥杯 ADV-165 算法提高 超级玛丽

算法提高 超级玛丽  

时间限制:1.0s   内存限制:256.0MB

问题描述
  大家都知道"超级玛丽"是一个很善于跳跃的探险家,他的拿手好戏是跳跃,但它一次只能向前跳一步或两步。有一次,他要经过一条长为n的羊肠小道,小道中有m个陷阱,这些陷阱都位于整数位置,分别是a1,a2,....am,陷入其中则必死无疑。显然,如果有两个挨着的陷阱,则玛丽是无论如何也跳过不去的。
  现在给出小道的长度n,陷阱的个数及位置。求出玛丽从位置1开始,有多少种跳跃方法能到达胜利的彼岸(到达位置n)。

输入格式
  第一行为两个整数n,m
  第二行为m个整数,表示陷阱的位置

输出格式
  一个整数。表示玛丽跳到n的方案数

样例输入
4 1
2

样例输出
1

数据规模和约定
  40>=n>=3,m>=1
  n>m;
  陷阱不会位于1及n上
 

分析:设f(i)是从1跳到i的所有方案数,其递推关系式为

f(i) = \begin{cases} f(i-1) + f(i-2) & \text{ if } i \text{ is not pitfall} \\ 0 & \text{ if } i \text{ is pitfall} \end{cases}

初始条件:

f(1) = 1

f(2) = \begin{cases} 1 & \text{ if } i \text{ is not pitfall} \\ 0 & \text{ if } i \text{ is pitfall} \end{cases}

#include <stdio.h>

int main()
{
    int n, m, pitfall;
    int is_pitfall[45] = { 0 };
    int f[45] = { 0 };

    scanf("%d %d", &n, &m);
    for (int i = 1; i <= m; ++i)
    {
        scanf("%d", &pitfall);
        is_pitfall[pitfall] = 1;
    }

    f[1] = 1;
    f[2] = !is_pitfall[2];
    for (int i = 3; i <= n; ++i)
    {
        if (is_pitfall[i])
            f[i] = 0;
        else
            f[i] = f[i-1] + f[i-2];
    }
    printf("%d", f[n]);

    return 0;
}
发布了298 篇原创文章 · 获赞 43 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/liulizhi1996/article/details/104237103
今日推荐