我是靠谱客的博主 漂亮香水,最近开发中收集的这篇文章主要介绍python解决上n级台阶问题,步长为3k+1,k为任一自然数,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Problem

竺竺为了追求漂亮温柔的学姐,决定走到学姐所在的第n级平台上,由于他心情欢快连跑带跳,他一次只能向上走1,4,7,10…(即3n+1)级台阶。竺竺想知道他有多少种方法走上这n级台阶,你能帮帮他吗?

Input

一行一个整数n(n<=10000),表示一共有n级台阶。

Output

一行一个整数,表示竺竺上台阶的方案数,结果对100003取余。

Sample Input

5

Sample Output

3

初步想法

def count(n),计算上n级台阶的方案数;
所有的方案按照最后一步的走法分类;
最后一步可能走1,4,7……,m;m是数列{3k+1}中不大于n的最大项;
那么按照加法原理:
c o u n t ( n ) = c o u n t ( n − 1 ) + c o u n t ( n − 4 ) + … … + c o u n t ( n − m ) count(n)=count(n-1)+count(n-4)+……+count(n-m) count(n)=count(n1)+count(n4)++count(nm)

代码一

def count(n):
	if n%3==0:   #先求得m
		m=i-2
	elif n%3==1:
 		m=i
	else:
		m=i-1
	if n<4:
		return 1    #递归出口
	else:
		s=sum([count(n-i) for i in range(1,m+3,3)])  #递归
		return s%100003
n=int(input())
print(count(n))
输入:50
输出:13886
耗时:54.8s

优化

递归显然是低效的,考虑逐项递推,来降低空间复杂度;
用字典键值对来存储(台阶数,方案数)

def count(n):
    l={0:1,1:1,2:1,3:1}   #字典存放--台阶数:方案数
    if n<4:
        return 1
    else:
        for i in range(4,n+1):   #求得{3k+1}数列中不大于i的最大项为m
            if i%3==0:
                m=i-2
            elif i%3==1:
                m=i
            else:
                m=i-1
            l[i]=sum([l[i-j] for j in range(1,m+3,3)])%100003   #同样的递推关系,用字典来操作
        return l[n]  #返回字典中键n的值
n=int(input())
print(cou(n))
输入:50;1000;10000,100000(除了这个程序其他都算不了十万)
输出:13886;56613;30763;37326
耗时:731ms;1.38s;5.29s;很久

另一种想法

换一种分类的方法,考虑走的步数;
假定走了m步,每一步走
3 k i + 1 , k i ∈ N , i = 1 , 2 , . . . , m 3k_i+1,k_iin N,i=1,2, ...,m 3ki+1kiNi=1,2,...,m
那么就得到
∑ i = 1 m ( 3 k i + 1 ) = n sum _{i=1}^m(3k_i+1)=n i=1m(3ki+1)=n
也就是
∑ i = 1 m k i = n − m 3 sum _{i=1}^mk_i={{n-m}over3} i=1mki=3nm
这个不定方程的解集的个数其实是很好求的。
这里要求 m ≡ n m o d    3 , 1 ≤ m ≤ n , m ∈ N ∗ mequiv n mod 3,1leq mleq n,min N^* mnmod31mn,mN方程才有解;
方程解集个数为 C n − m 3 + m − 1 m − 1 C_{{{n-m}over 3} +m-1}^{m-1} C3nm+m1m1
(这是个典型的组合问题,可以参考以下文章 链接???? )
在这里插入图片描述

接下来就是简单的编程问题了:

代码二

from scipy.special import comb   #借用scipy库计算组合数
def cou(n):
    sum_answer = 0
    for m in range(n,0,-3):  #m其实就是n-3k
        sum_answer += comb((n+2*m-3)/3,(n-m)/3,True)   
           #这里True参数表示结果用int表示,否则默认返回float
    return sum_answer%100003
n=int(input())
print(cou(n))
输入:50;1000;10000
输出:13886;56613;30763
耗时:728ms;1.36s;5.05s

实际上计算更大的数据时用组合数的方法就不再占优势(也可能是py的局限性),但是数学上岂不美哉~



以上

最后

以上就是漂亮香水为你收集整理的python解决上n级台阶问题,步长为3k+1,k为任一自然数的全部内容,希望文章能够帮你解决python解决上n级台阶问题,步长为3k+1,k为任一自然数所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(35)

评论列表共有 0 条评论

立即
投稿
返回
顶部