动态规划(poj):上楼梯问题的改进版

poj上机考试题目描述:

D:上楼梯

 

描述

小S在玩一个叫上楼梯的游戏。楼梯一共有n层台阶。

因为腿长的限制,小S每次最多只能上k层台阶。

小S是一个迷信的人,所以他不希望自己某一步走的步数的数字里有"4",(比如4,14,44都含有数字"4")。

现在,小S想要知道,有多少种走完这n层台阶的方案?

输入

输入包含多组数据。

每组数据第一行输入一个整数 n, k(1 <= k <= n <= 50)。

输入以 n,k=0 结束。

输出

对于每组数据,输出一行一个整数,表示答案。

样例输入

10 1
10 2
18 8
0 0

样例输出

1
89
71262

提示

注意答案可能超过 int 所能表示的范围,请谨慎选择存储答案以及中间数据的数据类型。

非常容易可以得到,每次可以走1  -  K层楼梯(不包括含有4的层数),那么第n层楼梯,要么是从第n - 1层直接到达,要么是从 n - 2 层, n -3 层 ... n - k层楼梯直接一步到达,所以有到达n的方法数 F[n] = F[n - 1] + F[n - 2] + ... + F[i - k]注意不能从含有4的步数 j 一步到达。

注意F[0] = 1是一个非常重要的设定,当 i - k == 0时,要能从0层1步到达。

代码为:

#include
#include
#include
using namespace std;

int F[51] = {0};

int main()
{
    int n, k;
    while(scanf("%d%d", &n, &k) != EOF)
    {
        memset(F, 0, sizeof(F));
        if(n == 0 && k == 0)
            break;
        F[0] = 1;
        F[1] = 1;
        for(int i = 2; i <= n; i++)
        {
            for(int j = 1; j <= k; j++)
            {
                int p = j;
                int flag = 1;
                while(p != 0)
                {
                    int r = p % 10;
                    if(r == 4)
                    {
                        flag = 0;
                        break;
                    }
                    p /= 10;
                }
                if(flag)
                    F[i] += F[i - j];
            }
        }
        printf("%d\n", F[n]);
    }
    return 0;
}

中包含string str = to_string(int i)的函数,但是有的编译器可能不支持。用str.find("4") == string::npos来判断不存在4.

当然也可以用上面的方法。另外要注意当多组输入时,要注意一些全局变量的重新初始化,memset().

 

 

你可能感兴趣的:(算法与数据结构,poj)