[アルゴリズム]動的計画法の基本的な質問バンク1-7Pythonの実装

醜い数

醜い数は、素因数が2、3、または5しかない数です。数列1、2、3、4、5、6、8、9、10、12、15、…は最初の11個の醜い番号を示しています。慣例により、1が含まれます。数nが与えられた場合、n番目の醜い数を見つけてください。

まず、数字が醜い数字であるかどうかを判断する方法は?この数を2、3、および5の可能な最大の累乗で割ります。1になると、それは醜い数になります。

醜い数の素因数は2、3、5しかないため、醜い数列の数は3つのグループに分けられます。

  1. 1x2、2x2、3x2、4x2、5x2、…
  2. 1x3、2x3、3x3、4x3、5x3、..。
  3. 1x5、2x5、3x5、4x5、5x5、..。

各サブシーケンスは、醜い数自体に2、3、および5を掛けたものです。したがって、マージソートのように3つのサブシリーズをマージすることで、すべての醜い数字を取得できます。

  1. 醜い数列を宣言します:ugly [n]

  2. 最初の醜い数を初期化します:ugly [0] = 1

  3. サブ配列の最初の要素を指すように、3つのサブ配列のインデックスを初期化します。i2= i3 = i5 = 0

  4. 次の3つの醜い数字の可能な値を初期化します:

    next_multiple_of_2 = ugly [i2] * 2;

    next_multiple_of_3 = ugly [i3] * 3;

    next_multiple_of_5 = ugly [i5] * 5;

  5. dp配列を埋める

import time


def getNthUglyNo(n):
    ugly = [0] * n
    ugly[0] = 1
    i2 = i3 = i5 = 0

    next_multiple_of_2 = 2
    next_multiple_of_3 = 3
    next_multiple_of_5 = 5

    for i in range(1, n):
        ugly[i] = min(next_multiple_of_2,
                      next_multiple_of_3,
                      next_multiple_of_5)

        if ugly[i] == next_multiple_of_2:
            i2 += 1
            next_multiple_of_2 = ugly[i2] * 2

        if ugly[i] == next_multiple_of_3:
            i3 += 1
            next_multiple_of_3 = ugly[i3] * 3

        if ugly[i] == next_multiple_of_5:
            i5 += 1
            next_multiple_of_5 = ugly[i5] * 5

    return ugly[-1]


# Driver code
time_start = time.time()
no = getNthUglyNo(150)
time_end = time.time()
print('150th ugly no is', no)
print('cost ', (time_end - time_start) * 1000, 'ms')

時間計算量はO(n)であるため、使用時に印刷する方法はありません。

フィボナッチ数列

0、1、1、2、3、5、8、13、21、34、55、89、144、…
数学的に説明します:
F n = F n-1 + F n-2
シード番号:F 0 = 0、F 1 = 1
数nが与えられた場合、n番目のフィボナッチ数を見つけます

前の質問と同様に、下から上にdp配列を作成します

def getNthFiboNo(n):
    Fibo = [0] * (n)
    Fibo[0] = 0
    Fibo[1] = 1
    if n <= 1:
        return Fibo[n]
    for i in range(2, n):
        Fibo[i] = Fibo[i - 2] + Fibo[i - 1]
    return Fibo[-1]


no = getNthFiboNo(9)
print('9th fibonacci no is', no)

# 9th fibonacci no is 21

カトレア番号

この記事は、カトレア番号の紹介が非常に明確です。また、dp配列を作成するための上記の2つの質問と同様です。

def getNthCatalanNo(n):
    if(n == 0 or n == 1):
        return 1
    catalan = [0] * n
    catalan[0] = 1
    catalan[1] = 1
    for i in range(2, n):
        for j in range(i):
            catalan[i] += catalan[j] * catalan[i - j - 1]
    return catalan[-1]


no = getNthCatalanNo(10)
print('10th catlan no is', no)

ベル数

アプリケーション:n個の要素のセットが与えられた場合、そのセットにはいくつのサブセットがありますか?
この問題の解はベル数であり、この数の漸化式は次のとおりです
。∑ k = 0 n S(n、k)\ sum_ {k = 0} ^ {n} S(n、k)k = 0n個S n k
S(n + 1、k)= k ∗ S(n、k)+ S(n、k − 1)S(n + 1、k)= k * S(n、k)+ S(n、 k-1)S n+1 k =kS n k +S n k1
別の方法は、ベルの三角形を使用して2桁のdp配列を作成し、解くことです。

1
1 2
2 3 5
5 7 10 15
15 20 27 37 52
def bellNumber(n):

    bell = [[0 for i in range(n+1)] for j in range(n+1)]
    bell[0][0] = 1
    for i in range(1, n+1):
        bell[i][0] = bell[i-1][i-1]

        for j in range(1, i+1):
            bell[i][j] = bell[i-1][j-1] + bell[i][j-1]

    return bell[n][0]


# Driver program
for n in range(6):
    print('Bell Number', n, 'is', bellNumber(n))

二項係数

二項係数C(n、k)は、(1 + x)nの展開におけるxkの係数として定義できます
この機能を実装してください。

まず、下部構造を分割します
。C(n、k)= C(n − 1、k − 1)+ C(n − 1、k)C(n、k)= C(n-1、k-1)+ C(n-1、k)C n k =C n1 k1 +C n1 k
C(n、0)= C(n、n)= 1 C(n、0)= C(n、n)= 1C n 0 =C n n =1
したがって、下部構造を繰り返してdp配列を作成します。

def binomalCoef(n, k):
    C = [[0 for i in range(k+1)] for i in range(n+1)]

    for i in range(n+1):
        for j in range(min(i, k)+1):
            if j == 0 or j == i:
                C[i][j] = 1
            else:
                C[i][j] = C[i-1][j-1] + C[i-1][j]
    return C[n][k]


n = 5
k = 2
print('binomial coefficient (5, 2) is', binomalCoef(n, k))

順列係数

順列とは、特定のセットのすべてのメンバーをシーケンスに配置するプロセスを指します。n個の要素のセットの順列の数はnの階乗です。
P(n、k)で表される配置係数は、n個の要素のセットからk個の要素の順序付けられたサブセットを取得する方法の数を表すために使用されます。
メソッドを実装します。

数学的知識を使用すると、この方法の解は次のようになります
。P(n、k)= n(n − 1)(n − 2)...(N − k + 1)(k <= n)P(n、k )= n(n-1)(n-2)...(n-k + 1)(k <= n)P n k =n n1 n2 nk+1 k<=n

P(n、k)= n!(n − k)!P(n、k)= \ frac {n!} {(nk)!}P n k =nk n個

したがって、

def permutationCoeff(n, k): 
  
    P = [[0 for i in range(k + 1)]  
            for j in range(n + 1)] 
  
    # 计算排列系数
    # 由底至上 
    for i in range(n + 1): 
        for j in range(min(i, k) + 1): 
  
            # 初始值
            if (j == 0): 
                P[i][j] = 1
   
            else: 
                P[i][j] = P[i - 1][j] + ( 
                           j * P[i - 1][j - 1]) 
  
            # 如果j小于k,则返回0
            if (j < k): 
                P[i][j + 1] = 0
    return P[n][k]


n = 10
k = 2
print("Value fo P(", n, ", ", k, ") is ", 
       permutationCoeff(n, k), sep = "")

おすすめ

転載: blog.csdn.net/qq_35714301/article/details/113760087