概述
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(n−1)+count(n−4)+……+count(n−m)
代码一
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+1,ki∈N,i=1,2,...,m
那么就得到
∑
i
=
1
m
(
3
k
i
+
1
)
=
n
sum _{i=1}^m(3k_i+1)=n
i=1∑m(3ki+1)=n
也就是
∑
i
=
1
m
k
i
=
n
−
m
3
sum _{i=1}^mk_i={{n-m}over3}
i=1∑mki=3n−m
这个不定方程的解集的个数其实是很好求的。
这里要求
m
≡
n
m
o
d
3
,
1
≤
m
≤
n
,
m
∈
N
∗
mequiv n mod 3,1leq mleq n,min N^*
m≡nmod3,1≤m≤n,m∈N∗方程才有解;
方程解集个数为
C
n
−
m
3
+
m
−
1
m
−
1
C_{{{n-m}over 3} +m-1}^{m-1}
C3n−m+m−1m−1
(这是个典型的组合问题,可以参考以下文章 链接???? )
接下来就是简单的编程问题了:
代码二
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为任一自然数所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复