<!DOCTYPE html>
    <html lang="vi" xmlns="http://www.w3.org/1999/xhtml" prefix="og: http://ogp.me/ns#">
    <head>
<title>Viết chương trình tính số cách leo cầu thang bằng Python</title>
<meta name="description" content="Viết chương trình tính số cách leo cầu thang bằng Python - Savefile - Tin Tức -...">
<meta name="author" content=".: Nguoicodonvn2008.info - Cõi lòng người cô đơn :.">
<meta name="copyright" content=".: Nguoicodonvn2008.info - Cõi lòng người cô đơn :. [admin@nguoicodonvn2008.info]">
<meta name="robots" content="index, archive, follow, noodp">
<meta name="googlebot" content="index,archive,follow,noodp">
<meta name="msnbot" content="all,index,follow">
<meta name="generator" content="NukeViet v4.5">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta property="og:title" content="Viết chương trình tính số cách leo cầu thang bằng Python">
<meta property="og:type" content="website">
<meta property="og:description" content="Savefile - Tin Tức - https&#x3A;&#x002F;&#x002F;www.nguoicodonvn2008.info&#x002F;vi&#x002F;news&#x002F;savefile&#x002F;kien-thuc-may-tinh&#x002F;viet-chuong-trinh-tinh-so-cach-leo-cau-thang-bang-python-6352.html">
<meta property="og:site_name" content=".&#x3A; Nguoicodonvn2008.info - Cõi lòng người cô đơn &#x3A;.">
<meta property="og:url" content="https://www.nguoicodonvn2008.info/vi/news/savefile/kien-thuc-may-tinh/viet-chuong-trinh-tinh-so-cach-leo-cau-thang-bang-python-6352.html">
<link rel="shortcut icon" href="https://www.nguoicodonvn2008.info/favicon.ico">
<link rel="canonical" href="https://www.nguoicodonvn2008.info/vi/news/savefile/kien-thuc-may-tinh/viet-chuong-trinh-tinh-so-cach-leo-cau-thang-bang-python-6352.html">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/" title="Tin Tức" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/karaoke-dual/" title="Tin Tức - Karaoke Dual" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/nhac-tre/" title="Tin Tức - Nhạc trẻ" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/tru-tinh/" title="Tin Tức - Trữ tình" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/nuoc-ngoai/" title="Tin Tức - Nước ngoài" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/remix/" title="Tin Tức - Remix" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/tam-su-tinh-yeu/" title="Tin Tức - Tâm sự tình yêu" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/tho-suu-tam/" title="Tin Tức - Thơ sưu tầm" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/cuoc-song/" title="Tin Tức - Cuộc sống" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/phan-mem/" title="Tin Tức - Phần mềm" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/kien-thuc-may-tinh/" title="Tin Tức - Kiến thức máy tính" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/hoc-tap/" title="Tin Tức - Học tập" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/tai-lieu/" title="Tin Tức - Tài liệu" type="application/rss+xml">
<link rel="alternate" href="https://www.nguoicodonvn2008.info/vi/news/rss/de-thi/" title="Tin Tức - Đề thi" type="application/rss+xml">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/assets/css/font-awesome.min.css" type="text/css">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/themes/default/css/bootstrap.non-responsive.css" type="text/css">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/themes/default/css/style.css" type="text/css">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/themes/default/css/style.non-responsive.css" type="text/css">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/themes/default/css/news.css" type="text/css">
<link rel="preload" as="style" href="https://www.nguoicodonvn2008.info/themes/default/css/custom.css" type="text/css">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/assets/js/jquery/jquery.min.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/assets/js/language/vi.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/assets/js/DOMPurify/purify3.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/assets/js/global.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/assets/js/site.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/themes/default/js/news.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/themes/default/js/main.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/themes/default/js/custom.js" type="text/javascript">
<link rel="preload" as="script" href="https://www.nguoicodonvn2008.info/themes/default/js/bootstrap.min.js" type="text/javascript">
<link rel="stylesheet" href="https://www.nguoicodonvn2008.info/assets/css/font-awesome.min.css">
<link rel="stylesheet" href="https://www.nguoicodonvn2008.info/themes/default/css/bootstrap.non-responsive.css">
<link rel="stylesheet" href="https://www.nguoicodonvn2008.info/themes/default/css/style.css">
<link rel="stylesheet" href="https://www.nguoicodonvn2008.info/themes/default/css/style.non-responsive.css">
<link rel="StyleSheet" href="https://www.nguoicodonvn2008.info/themes/default/css/news.css">
<link rel="stylesheet" href="https://www.nguoicodonvn2008.info/themes/default/css/custom.css">
<style type="text/css">
	body{background: #fff;}
</style>
    </head>
    <body>
<div id="print">
	<div id="hd_print">
		<h2 class="pull-left">.&#x3A; Nguoicodonvn2008.info - Cõi lòng người cô đơn &#x3A;.</h2>
		<p class="pull-right"><a title=".&#x3A; Nguoicodonvn2008.info - Cõi lòng người cô đơn &#x3A;." href="https://www.nguoicodonvn2008.info/">https://www.nguoicodonvn2008.info</a></p>
	</div>
	<div class="clear"></div>
	<hr />
	<div id="content">
		<h1>Viết chương trình tính số cách leo cầu thang bằng Python</h1>
		<ul class="list-inline">
			<li>Chủ nhật - 20/11/2022 23:17</li>
			<li class="hidden-print txtrequired"><em class="fa fa-print">&nbsp;</em><a title="In ra" href="javascript:;" onclick="window.print()">In ra</a></li>
			<li class="hidden-print txtrequired"><em class="fa fa-power-off">&nbsp;</em><a title="Đóng cửa sổ này" href="javascript:;" onclick="window.close()">Đóng cửa sổ này</a></li>
		</ul>
		<div class="clear"></div>
		<div id="hometext">
		</div>
				<div class="imghome">
			<img alt="Viết chương trình tính số cách leo cầu thang bằng Python" src="https://st.quantrimang.com/photos/image/2022/11/21/viet-chuong-trinh-tinh-so-cach-leo-cau-thang-bang-python.jpg" width="460" class="img-thumbnail" />
		</div>
		<div class="clear"></div>
		<div id="bodytext" class="clearfix">
			<p style="text-align: justify;"><strong>Đề bài</strong>: Cho n bậc cầu thang, một người đứng ở dưới chân cầu thang muốn leo lên đỉnh. Người này có thể bước 1 bậc hoặc 2 bậc mỗi lần. Đếm số cách người đó có thể làm để lên tới đỉnh.</p>

<p style="text-align: justify;">Bạn có thể nhìn ví dụ trong ảnh. Giá trị của n là 3 và có 3 cách để bước lên đỉnh.</p>

<p style="text-align: justify;"><img alt="Viết chương trình tính số cách leo cầu thang bằng Python" data-i="0" data-src="https://st.quantrimang.com/photos/image/2022/11/21/viet-chuong-trinh-tinh-so-cach-leo-cau-thang-bang-python.jpg" data-was-processed="true" height="320" src="https://st.quantrimang.com/photos/image/2022/11/21/viet-chuong-trinh-tinh-so-cach-leo-cau-thang-bang-python.jpg" width="354" /></p>

<p style="text-align: justify;">Ví dụ:</p>

<pre id="pre0">
<code>Input: n = 1
Output: 1
There is only one way to climb 1 stair

Input: n = 2
Output: 2
There are two ways: (1, 1) and (2)

Input: n = 4
Output: 5
(1, 1, 1, 1), (1, 1, 2), (2, 1, 1), (1, 2, 1), (2, 2) </code></pre>

<p style="text-align: justify;">Trong bài viết này, Quản Trị Mạng sẽ cùng các bạn tìm hiểu cách viết chương trình đếm số cách leo cầu thang bằng&nbsp;<a href="https://quantrimang.com/hoc/hoc-python" title="Python">Python</a>.</p>

<h2 style="text-align: justify;">Cách 1: Chúng ta sẽ sử dụng đệ quy để giải quyết vấn đề này</h2>

<p style="text-align: justify;">Ta dễ dàng nhận thấy tính chất đệ quy trong bài toán này. Người đó có thể đến bậc thang thứ n từ bậc thang thứ n-1 hoặc bậc thang thứ n-2. Do đó, đối với mỗi bậc thang n, chúng ta hãy cố gắng tìm ra số cách để đi đến bậc thang thứ n-1 và n-2 và thêm chúng để đưa ra câu trả lời cho bậc thang thứ n. Với cách tiếp cận này, chúng ta có biểu thức sau:</p>

<pre id="pre1">
<code>ways(n) = ways(n-1) + ways(n-2)</code></pre>

<p style="text-align: justify;">Biểu thức trên thực chất là biểu thức của các số Fibonacci nhưng có một điều cần lưu ý là giá trị của ways(n) bằng với fibonacci(n+1).</p>

<pre id="pre2">
<code>ways(1) = fib(2) = 1
ways(2) = fib(3) = 2
ways(3) = fib(4) = 3</code></pre>

<p style="text-align: justify;">Để hiểu rõ hơn, chúng ta hãy tham khảo cây đệ quy bên dưới đây:</p>

<pre id="pre3">
<code>Input: N = 4

                  fib(5)
           &#039;3&#039;  /        \   &#039;2&#039;
               /          \
           fib(4)         fib(3)
     &#039;2&#039;  /      \ &#039;1&#039;   /      \  
         /        \     /        \ 
     fib(3)     fib(2)fib(2)      fib(1) 
     /    \ &#039;1&#039; /   \ &#039;0&#039;
&#039;1&#039; /   &#039;1&#039;\   /     \ 
   /        \ fib(1) fib(0) 
fib(2)     fib(1)</code></pre>

<p style="text-align: justify;">Vì vậy, chúng ta có thể sử dụng hàm cho số Fibonacci để tìm giá trị của ways(n). Dưới đây là code mẫu:</p>

<pre id="pre4" style="text-align: justify;">
# Python program to count
# ways to reach nth stair
# Recursive function to find
# Nth fibonacci number
def fib(n):
    if n &lt;= 1:
        return n
    return fib(n-1) + fib(n-2)
# Returns no. of ways to
# reach sth stair
def countWays(s):
    return fib(s + 1)
# Driver program
s = 4
print &quot;Số cách là = &quot;,
print countWays(s)
# Contributed by Harshit Agrawal</pre>

<h3 style="text-align: justify;">Khái quát hóa vấn đề</h3>

<p style="text-align: justify;">Làm thế nào để đếm số cách nếu một người có thể leo m bậc cầu thang với một số m cho trước. Ví dụ m là 4 thì người đó có thể leo 1 bậc thang, 2 bậc thang, 3 bậc thang hoặc 4 bậc thang cùng lúc.</p>

<p style="text-align: justify;">Để khái quát hóa cách tiếp cận trên, chúng ta có thể sử dụng quan hệ đệ quy sau:</p>

<pre id="pre5">
<code>ways(n, m) = ways(n-1, m) + ways(n-2, m) + ... ways(n-m, m) </code></pre>

<p style="text-align: justify;">Trong cách tiếp cận này, để đến cầu thang thứ n, hãy thử leo lên tất cả số bậc thang ít hơn n so với cầu thang hiện tại.</p>

<p style="text-align: justify;">Sau đây là code mẫu cho phần khái quát này:</p>

<pre id="pre6" style="text-align: justify;">
# A program to count the number of ways
# to reach n&#039;th stair
# Recursive function used by countWays
def countWaysUtil(n, m):
    if n &lt;= 1:
        return n
    res = 0
    i = 1
    while i&lt;= m and i&lt;= n:
        res = res + countWaysUtil(n-i, m)
        i = i + 1
    return res
# Returns number of ways to reach s&#039;th stair   
def countWays(s, m):
    return countWaysUtil(s + 1, m)
# Driver program
s, m = 4, 2
print &quot;Số cách là =&quot;, countWays(s, m)
# Contributed by Harshit Agrawal</pre>

<h2 style="text-align: justify;">Cách 2: Ghi nhớ</h2>

<p style="text-align: justify;">Chúng ta cũng có thể sử dụng cách tiếp cận từ dưới lên của dp để giải quyết vấn đề này.</p>

<p style="text-align: justify;">Chúng ta có thể tạo một mảng dp&#91;&#93; và khởi tạo nó với -1.</p>

<p style="text-align: justify;">Bất cứ khi nào chúng ta thấy rằng một bài toán con không được giải quyết, chúng ta có thể gọi phương thức đệ quy.</p>

<p style="text-align: justify;">Mặt khác, chúng ta dừng đệ quy nếu bài toán con đó đã được giải quyết.</p>

<p style="text-align: justify;">Code mẫu như sau:</p>

<pre id="pre7" style="text-align: justify;">
# Python program to count number of
# ways to reach Nth stair
# A simple recursive program to
# find N&#039;th fibonacci number
def fib(n, dp):
    if (n &lt;= 1):
        return 1
    if(dp&#91;n&#93; != -1 ):
        return dp&#91;n&#93;
    dp&#91;n&#93; = fib(n - 1, dp) + fib(n - 2, dp)
    return  dp&#91;n&#93;
# Returns number of ways to
# reach s&#039;th stair
def countWays(n):
    dp = &#91;-1 for i in range(n + 1)&#93;
    fib(n, dp)
    return dp&#91;n&#93;
# Driver Code
n = 4
print(&quot;Số cách là = &quot; + str(countWays(n)))
# This code is contributed by shinjanpatra</pre>

<h2 style="text-align: justify;">Cách 3: Dynamic Programming</h2>

<p style="text-align: justify;">Cách này sử dụng kỹ thuật Dynamic Programming để giải quyết bài toán.</p>

<p style="text-align: justify;">Chúng ta tạo ra một bảng res&#91;&#93; theo cách từ dưới lên bằng cách sử dụng mối quan hệ sau:</p>

<pre id="pre8">
<code>res&#91;i&#93; = res&#91;i&#93; + res&#91;i-j&#93; for every (i-j) &gt;= 0</code></pre>

<p style="text-align: justify;">Do đó, chỉ số thứ i của mảng sẽ chứa số cách cần thiết để bước tới bậc thứ i&nbsp; có tính đến tất cả các khả năng leo (tức là từ 1 tới i).</p>

<p style="text-align: justify;">Dưới đây là code mẫu theo cách tiếp cận này:</p>

<pre id="pre9" style="text-align: justify;">
# A program to count the number of
# ways to reach n&#039;th stair
# Recursive function used by countWays
def countWaysUtil(n, m):
    # Creates list res with all elements 0
    res = &#91;0 for x in range(n)&#93;
    res&#91;0&#93;, res&#91;1&#93; = 1, 1
    for i in range(2, n):
        j = 1
        while j&lt;= m and j&lt;= i:
            res&#91;i&#93; = res&#91;i&#93; + res&#91;i-j&#93;
            j = j + 1
    return res&#91;n-1&#93;
# Returns number of ways to reach s&#039;th stair
def countWays(s, m):
    return countWaysUtil(s + 1, m)
# Driver Program
s, m = 4, 2
print &quot;Số cách là =&quot;, countWays(s, m)
# Contributed by Harshit Agrawal</pre>

<h2 style="text-align: justify;">Cách 4: Sử dụng Sliding Windows</h2>

<p style="text-align: justify;">Trong cách này, chúng ta sẽ sử dụng Dymanic Programming Approach một cách hiệu quả hơn.</p>

<p style="text-align: justify;">Trong cách tiếp cận cho cầu thang thứ i này, chúng ta giữ một cửa sổ chứa tổng số m cầu thang cuối cùng mà có thể từ đó chúng ta leo lên cầu thang thứ i. Thay vì chạy một vòng lặp bên trong, chúng ta duy trì kết quả của vòng lặp bên trong một biến tạm thời. Chúng ta xóa các phần tử của cửa sổ trước đó và thêm phần tử của cửa sổ hiện tại.</p>

<p style="text-align: justify;">Dưới đây là code mẫu:</p>

<pre id="pre10" style="text-align: justify;">
# Python3 program to count the number
# of ways to reach n&#039;th stair when
# user climb 1 .. m stairs at a time.
# Function to count number of ways
# to reach s&#039;th stair
def countWays(n, m):
    temp = 0
    res = &#91;1&#93;
    for i in range(1, n + 1):
        s = i - m - 1
        e = i - 1
        if (s &gt;= 0):
            temp -= res&#91;s&#93;
        temp += res&#91;e&#93;
        res.append(temp)
    return res&#91;n&#93;
# Driver Code
n = 5
m = 3
print(&#039;Số cách là =&#039;, countWays(n, m))
# This code is contributed by 31ajaydandge</pre>

<h2 style="text-align: justify;">Cách 5: Sử dụng toán học đơn thuần</h2>

<p style="text-align: justify;">Trong cách tiếp cận này, chúng ta chỉ đơn giản là đếm số số tập hợp có 2. Phương pháp này chỉ được áp dụng nếu như vấn đề thứ tự trong khi đếm bước không quan trọng.</p>

<pre id="pre11" style="text-align: justify;">
# Here n/2 is done to count the number 2&#039;s in n
# 1 is added for case where there is no 2.
# eg: if n=4 ans will be 3.
# {1,1,1,1} set having no 2.
# {1,1,2} ans {2,2} (n/2) sets containing 2.
print(&quot;Number of ways when order &quot;
      &quot;of steps does not matter is : &quot;, 1 + (n // 2)) 
# This code is contributed by rohitsingh07052</pre>

<h2 style="text-align: justify;">Cách 6: Sử dụng kỹ thuật Matrix Exponentitation</h2>

<p style="text-align: justify;">Trong cách này, chúng ta sử dụng kỹ thuật Matrix Exponentitation để giải quyết bài toán.</p>

<p style="text-align: justify;">Số lượng cách để bước lên bậc thang thứ n (có xét thứ tự) bằng với tổng lượt cách bước lên bật thang thứ n-1 và bậc thang thứ n-2.</p>

<p style="text-align: justify;">Điều này tương ứng với mối quan hệ lặp lại sau:</p>

<pre id="pre12">
<code>f(n) = f(n-1) + f(n-2)

f(1) = 1
f(2) = 2</code></pre>

<p style="text-align: justify;">trong đó f(n) chỉ số cách bước tới bậc thang thứ n.</p>

<p style="text-align: justify;"><strong>Lưu ý:</strong></p>

<pre id="pre13">
<code>f(1) = 1 vì chỉ có 1 cách bước lên đỉnh cầu thang có 1 bậc, n=1, {1}

f(2) = 2 vì chỉ có 2 cách bước lên đỉnh cầu thang có 1 bậc, n=2, {1,1},{2}</code></pre>

<p style="text-align: justify;">Nó là một loại quan hệ truy hồi tuyến tính với các hệ số không đổi và chúng ta có thể giải chúng bằng phương pháp lũy thừa ma trận. Về cơ bản, phương pháp này tìm ma trận biến đổi cho một quan hệ truy hồi đã cho và áp dụng lặp lại phép biến đổi này cho một vectơ cơ sở để tìm ra giải pháp.</p>

<p style="text-align: justify;"><code>F(n) = C<sup>N-1</sup>F(1)</code></p>

<p style="text-align: justify;">trong đó C là ma trận biến đổi, F(1) là vectơ cơ sở và F(n) là giải pháp mong muốn.</p>

<p style="text-align: justify;">Do đó, trong trường hợp của chúng ta ma trận C sẽ là:</p>

<pre id="pre14">
<code>0	1
1	1</code></pre>

<p style="text-align: justify;">C<sup>N-1&nbsp;</sup>có thể được tính toán bằng kỹ thuật Divide and Conquer, trong O((K^3) Log n) với K là kích thước của C.</p>

<p style="text-align: justify;">Và F(1):</p>

<pre id="pre15">
<code>1
2</code></pre>

<p style="text-align: justify;">Ví dụ, cho n=4:</p>

<p style="text-align: justify;">F(4) = C<sup>3</sup>F(1)</p>

<p style="text-align: justify;">C<sup>3</sup>&nbsp;=</p>

<pre id="pre16">
<code>1	2
2	3</code></pre>

<p style="text-align: justify;">Do vậy, C<sup>3</sup>F(1) =</p>

<pre id="pre17">
<code>5
8</code></pre>

<p style="text-align: justify;">Code mẫu như sau:</p>

<pre id="pre18" style="text-align: justify;">
# Computes A*B
# where A,B are square matrices
def mul(A, B, MOD):
    K = len(A);
    C = &#91;&#91;0 for i in range(K)&#93; for j in range(K)&#93; ;
    for i in range(1, K):
        for j in range(1, K):
            for k in range(1, K):
                C&#91;i&#93;&#91;j&#93; = (C&#91;i&#93;&#91;j&#93; + A&#91;i&#93;&#91;k&#93; * B&#91;k&#93;&#91;j&#93;) % MOD;
    return C;
# Computes A^n
def power( A,  n):
    if (n == 1):
        return A;
    if (n % 2 != 0):
        # n is odd
        # A^n = A * &#91; A^(n-1) &#93;
        A = mul(A, power(A, n - 1), 1000000007);
    else:
        # n is even
        # A^n = &#91; A^(n/2) &#93; * &#91; A^(n/2) &#93;
        A = power(A, n // 2);
        A = mul(A, A, 1000000007);
    return A;
def ways(n):
    F = &#91;0 for i in range(3)&#93;;
    F&#91;1&#93; = 1;
    F&#91;2&#93; = 2;
    K = 2;
    MOD = 1000000007;
    # create K*K matrix
    C = &#91;&#91;0 for i in range(K+1)&#93; for j in range(K+1)&#93;;
    &#039;&#039;&#039;
     * A matrix with (i+1)th element as 1 and last row contains constants &#91; &#91;0 1 0 0
     * ... 0&#93; &#91;0 0 1 0 ... 0&#93; &#91;0 0 0 1 ... 0&#93; &#91;. . . . ... .&#93; &#91;. . . . ... .&#93; &#91;c(k)
     * c(k-1) c(k-2) ... c1&#93; &#93;
     &#039;&#039;&#039;
    for i in range(1,K):
        C&#91;i&#93;&#91;i + 1&#93; = 1;
    # Last row is the constants c(k) c(k-1) ... c1
    # f(n) = 1*f(n-1) + 1*f(n-2)
    C&#91;K&#93;&#91;1&#93; = 1;
    C&#91;K&#93;&#91;2&#93; = 1;
    if (n &lt;= 2):
        return F&#91;n&#93;;
    # f(n) = C^(n-1)*F
    C = power(C, n - 1);
    result = 0;
    # result will be the first row of C^(n-1)*F
    for i in range(1,K+1):
        result = (result + C&#91;1&#93;&#91;i&#93; * F&#91;i&#93;) % MOD;
    return result;
# Driver code
if __name__ == &#039;__main__&#039;:
    n = 4;
    print(&quot;Số cách là = &quot; , ways(n) , &quot;&quot;);
# This code is contributed by gauravrajput1</pre>

<h3 style="text-align: justify;">Khái quát hóa vấn đề</h3>

<p style="text-align: justify;">Cho một mảng&nbsp; A{a1, a2, ..., am} chứa tất cả các bước hợp lệ, tính số bước cần thiết để bước lên bậc thang thứ n, có tính thứ tự.</p>

<p style="text-align: justify;">Ví dụ:</p>

<pre id="pre19">
<code>Input:
    A = &#91;1,2&#93; 
    n = 4  
Output: 5  
Giải thích:
Tìm số cách để leo lên bậc thang thứ 4, mỗi lần có thể leo 1 hoặc 2 bước.
Số cách là: {1,1,1,1} {1,1,2} {1,2,1} {2,1,1} {2,2} = 5
Input:
    A = &#91;2,4,5&#93;
    n = 9
Output: 5
Giải thích:
Có 5 cách để leo lên bậc thang thứ 9 với khả năng leo 2 hoặc 4 hoặc 5 bậc thang mỗi lần.
Số cách là: {5,4} {4,5} {2,2,5} {2,5,2} {5,2,2} = 5 
</code></pre>

<p style="text-align: justify;">Số cách để leo tới bậc thang thứ n được cho bởi hệ thức truy hồi sau:</p>

<p style="text-align: justify;"><img alt="Viết chương trình tính số cách leo cầu thang bằng Python" data-i="1" data-src="https://st.quantrimang.com/photos/image/2022/11/21/viet-chuong-trinh-tinh-so-cach-leo-cau-thang-bang-python-1.jpg" data-was-processed="true" height="18" src="https://st.quantrimang.com/photos/image/2022/11/21/viet-chuong-trinh-tinh-so-cach-leo-cau-thang-bang-python-1.jpg" width="151" /></p>

<p style="text-align: justify;">Gọi K là phần tử lớn nhất trong A.</p>

<h4 style="text-align: justify;">Bước 1: Tính vectơ cơ sở F(1) (gồm f(1)... f(K))</h4>

<p style="text-align: justify;">Nó có thể được thực hiện trong thời gian O(m2K) bằng cách sử dụng phương pháp lập trình động như sau:</p>

<p style="text-align: justify;">Hãy lẫy A = {2,4,5&#93; làm ví dụ. Để tính F(1) = {f(1), f(2), f(3), f(4), f(5)}, chúng ta sẽ duy trì một mảng trống ban đầu và lặp lại nối Ai với nó và cho mỗi Ai chúng ta sẽ tìm số cách để đạt được &#91;Ai-1, tới Ai&#93;.</p>

<p style="text-align: justify;">Do đó, với A = {2, 4, 5&#93;</p>

<p style="text-align: justify;">Gọi T là mảng trống ban đầu:</p>

<pre id="pre20">
<code>Iteration 1: T = {2}        n = {1,2}        dp = {0,1}         (Number of ways to reach n=1,2 with steps given by T) 
Iteration 2: T = {2,4}        n = {1,2,3,4}    dp = {0,1,0,2}     (Number of ways to reach n=1,2,3,4 with steps given by T)
Iteration 3: T = {2,4,5}    n = {1,2,3,4,5}    dp = {0,1,0,2,1} (Number of ways to reach n=1,2,3,4,5 with steps given by T)</code></pre>

<p style="text-align: justify;">Lưu ý: vì một số giá trị đã được tính toán (1,2 cho lần lặp 2...) chúng ta có thể tránh chúng trong vòng lặp.</p>

<p style="text-align: justify;">Sau tất cả các lần lặp, mảng dp sẽ là: &#91;0,1,0,2,1&#93;</p>

<p style="text-align: justify;">Do đó vectơ cơ sở F(1) cho A = &#91;2,4,5&#93; là:</p>

<pre id="pre21">
<code>0
1
0
2
1</code></pre>

<p style="text-align: justify;">Bây giờ chúng ta có vectơ cơ sở F(1), việc tính toán C (ma trận biến đổi) là khá dễ dàng.</p>

<h4 style="text-align: justify;">Bước 2: Tính C, ma trận biến đổi</h4>

<p style="text-align: justify;">Đó là một ma trận với các phần tử Ai, i+1 = 1 và hàng cuối cùng chứa các hằng số.</p>

<p style="text-align: justify;">Bây giờ, các hằng số có thể được xác định bởi sự có mặt của phần tử đó trong A.</p>

<p style="text-align: justify;">Vì vậy, đối với A = &#91;2,4,5&#93; các hằng số sẽ là c = &#91;1,1,0,1,0&#93; (Ci = 1 nếu K-i+1) có mặt trong A, hoặc 0 nếu 1 &lt;= i &lt;= K.</p>

<p style="text-align: justify;">Do đó, ma trận biến đổi C cho A = &#91;2,4,5&#93; là:</p>

<pre id="pre22">
<code>0	1	0	0	0
0	0	1	0	0
0	0	0	1	0
0	0	0	0	1
1	1	0	1	0</code></pre>

<h4 style="text-align: justify;">Bước 3: Tính F(n)</h4>

<p style="text-align: justify;">Để tính F(n), công thức sau được sử dụng:</p>

<p style="text-align: justify;"><code>F(n) - C<sup>n-1</sup>F(1)</code></p>

<p style="text-align: justify;">Bây giờ chúng ta đã có C và F(1), chúng ta có thể sử dụng kỹ thuật Divide and Conquer để tìm&nbsp; C<sup>n-1</sup>&nbsp;và từ đó tìm ra kết quả đầu ra.</p>

<p style="text-align: justify;">Dưới đây là code mẫu:</p>

<pre id="pre23" style="text-align: justify;">
# Computes A*B when A,B are square matrices of equal
# dimensions)
def mul(A, B, MOD):
    K = len(A);
    C = &#91;&#91;0 for i in range(K)&#93; for j in range(K)&#93; ;
    for i in range(1, K):
        for j in range(1, K):
            for k in range(1, K):
                C&#91;i&#93;&#91;j&#93; = (C&#91;i&#93;&#91;j&#93; + A&#91;i&#93;&#91;k&#93; * B&#91;k&#93;&#91;j&#93;) % MOD;
    return C;
def power(A, n):
    if (n == 1):
        return A;
    if (n % 2 != 0):
        # n is odd
        # A^n = A * &#91; A^(n-1) &#93;
        A = mul(A, power(A, n - 1), 1000000007);
    else:
        # n is even
        # A^n = &#91; A^(n/2) &#93; * &#91; A^(n/2) &#93;
        A = power(A, n // 2);
        A = mul(A, A, 1000000007);
    return A;
def initialize(A):
    # Initializes the base vector F(1)
    K = A&#91;len(A)-1&#93;; # Assuming A is sorted
    F = &#91;0 for i in range(K+1)&#93;;
    dp = &#91;0 for i in range(K+1)&#93;;
    dp&#91;0&#93; = 0;
    dp&#91;A&#91;1&#93;&#93; = 1; # There is one and only one way to reach
    # first element
    F&#91;A&#91;1&#93;&#93; = 1;
    for i in range(2,len(A)):
        # Loop through A&#91;i-1&#93; to A&#91;i&#93; and fill the dp array
        for j in range(A&#91;i - 1&#93; + 1,A&#91;i&#93;+1):
            # dp&#91;j&#93; = dp&#91;j-A&#91;0&#93;&#93; + .. + dp&#91;j-A&#91;i-1&#93;&#93;
            for k in range(1,i):
                dp&#91;j&#93; += dp&#91;j - A&#91;k&#93;&#93;;
        # There will be one more way to reach A&#91;i&#93;
        dp&#91;A&#91;i&#93;&#93; += 1;
        F&#91;A&#91;i&#93;&#93; = dp&#91;A&#91;i&#93;&#93;;
    return F;
def ways(A, n):
    K = A&#91;len(A) - 1&#93;; # Assuming A is sorted
    F = initialize(A); # O(m^2*K)
    MOD = 1000000007;
    # create K*K matrix
    C = &#91;&#91;0 for i in range(K+1)&#93; for j in range(K+1)&#93;;
    &#039;&#039;&#039;
     * A matrix with (i+1)th element as 1 and last row contains constants &#91; &#91;0 1 0 0
     * ... 0&#93; &#91;0 0 1 0 ... 0&#93; &#91;0 0 0 1 ... 0&#93; &#91;. . . . ... .&#93; &#91;. . . . ... .&#93; &#91;c(k)
     * c(k-1) c(k-2) ... c1&#93; &#93;
     &#039;&#039;&#039;
    for i in range(1,K):
        C&#91;i&#93;&#91;i + 1&#93; = 1;
    # Last row is the constants c(k) c(k-1) ... c1
    # f(n) = 1*f(n-1) + 1*f(n-2)
    for i in range(1, len(A)):
        C&#91;K&#93;&#91;K - A&#91;i&#93; + 1&#93; = 1;
    if (n &lt;= K):
        return F&#91;n&#93;;
    # F(n) = C^(n-1)*F
    C = power(C, n - 1); # O(k^3Log(n))
    result = 0;
    # result will be the first row of C^(n-1)*F
    for i in range(1, K+1):
        result = (result + C&#91;1&#93;&#91;i&#93; * F&#91;i&#93;) % MOD;
    return result;
# Driver code
if __name__ == &#039;__main__&#039;:
    n = 9;
    A = &#91; 0, 2, 4, 5&#93; ;
    # 0 is just because we are using 1 based indexing
    print(&quot;Số lượng cách là = &quot; ,ways(A, n));
# This code is contributed by gauravrajput1</pre>

<p style="text-align: justify;"><strong>Lưu ý</strong>: Cách tiếp cận này là lý tưởng khi n quá lớn, không thể dùng vòng lặp.</p>

<p style="text-align: justify;"><strong>Ví dụ</strong>: Bạn nên xem xét cách tiếp cận này khi 1&lt;= n &lt;= 109 và 1 &lt;= m,k &lt;= 102.</p>

<p style="text-align: justify;">Hy vọng rằng bài viết này sẽ có ích với các bạn.</p>
		</div>
				<div id="author">
						<p>
				<strong>Nguồn tin:</strong>
				Quantrimang.com
			</p>
		</div>
	</div>
	<div id="footer" class="clearfix">
		<div id="url">
			<strong>URL của bản tin này: </strong><a href="https://www.nguoicodonvn2008.info/vi/news/savefile/kien-thuc-may-tinh/viet-chuong-trinh-tinh-so-cach-leo-cau-thang-bang-python-6352.html" title="Viết chương trình tính số cách leo cầu thang bằng Python">https://www.nguoicodonvn2008.info/vi/news/savefile/kien-thuc-may-tinh/viet-chuong-trinh-tinh-so-cach-leo-cau-thang-bang-python-6352.html</a>

		</div>
		<div class="clear"></div>
		<div class="copyright">
			&copy; .&#x3A; Nguoicodonvn2008.info - Cõi lòng người cô đơn &#x3A;.
		</div>
		<div id="contact">
			<a href="mailto:admin@nguoicodonvn2008.info">admin@nguoicodonvn2008.info</a>
		</div>
	</div>
</div>
        <div id="timeoutsess" class="chromeframe">
            Bạn đã không sử dụng Site, <a onclick="timeoutsesscancel();" href="https://www.nguoicodonvn2008.info/#">Bấm vào đây để duy trì trạng thái đăng nhập</a>. Thời gian chờ: <span id="secField"> 60 </span> giây
        </div>
        <div id="openidResult" class="nv-alert" style="display:none"></div>
        <div id="openidBt" data-result="" data-redirect=""></div>
		</script>
		<div class="car-top">
  <span><img src="https://www.nguoicodonvn2008.info/themes/default/images/car.png" alt=""></span>
</div>
<script src="https://www.nguoicodonvn2008.info/assets/js/jquery/jquery.min.js"></script>
<script>var nv_base_siteurl="/",nv_lang_data="vi",nv_lang_interface="vi",nv_name_variable="nv",nv_fc_variable="op",nv_lang_variable="language",nv_module_name="news",nv_func_name="savefile",nv_is_user=0, nv_my_ofs=-4,nv_my_abbr="EDT",nv_cookie_prefix="nv4c_e856T",nv_check_pass_mstime=1738000,nv_area_admin=0,nv_safemode=0,theme_responsive=0,nv_recaptcha_ver=2,nv_recaptcha_sitekey="",nv_recaptcha_type="image",XSSsanitize=1;</script>
<script src="https://www.nguoicodonvn2008.info/assets/js/language/vi.js"></script>
<script src="https://www.nguoicodonvn2008.info/assets/js/DOMPurify/purify3.js"></script>
<script src="https://www.nguoicodonvn2008.info/assets/js/global.js"></script>
<script src="https://www.nguoicodonvn2008.info/assets/js/site.js"></script>
<script src="https://www.nguoicodonvn2008.info/themes/default/js/news.js"></script>
<script src="https://www.nguoicodonvn2008.info/themes/default/js/main.js"></script>
<script src="https://www.nguoicodonvn2008.info/themes/default/js/custom.js"></script>
<script type="application/ld+json">
        {
            "@context": "https://schema.org",
            "@type": "Organization",
            "url": "https://www.nguoicodonvn2008.info",
            "logo": "https://www.nguoicodonvn2008.info/uploads/angel.gif"
        }
        </script>
<script src="https://www.nguoicodonvn2008.info/themes/default/js/bootstrap.min.js"></script>
<script type="text/javascript">
var $scrolltop = $('.car-top');
$scrolltop.on('click', function () {
    $('html,body').animate({
        scrollTop: 0
    }, 800);
    $(this).addClass("car-run");
    setTimeout(function(){ $scrolltop.removeClass('car-run');}, 1000);
    return false;
});
$(window).on('scroll', function ()
{ 
    if($(window).scrollTop() >= 200)
    {
        $scrolltop.addClass("show");
        $scrolltop.addClass("car-down");
    }
    else
    {
       $scrolltop.removeClass("show");
       setTimeout(function(){ $scrolltop.removeClass('car-down');}, 300);
    }
});
</script>
</body>
</html>