簡體   English   中英

如何用動態編程解決這個問題?

[英]how can solve this problem with dynamic programming?

說明 :老鼠可以向上或向右移動

輸入

  • 第一行包含表大小n的數量和干酪m的數量。
  • 從下一行開始,給出了奶酪的位置x,y

輸出:

  • 吃的最大奶酪數量

Exemple1:

  • 輸入: 1 1 1
  • 輸出: 1 1

例2:

  • 輸入:
3 2
1 2
3 1
  • 輸出: 1

例3:

  • 輸入:
5 5
2 3
3 2
4 3
4 5
5 2
  • 輸出: 3

我怎么能用python解決? 我試過了

def maxAverageOfPath(table, N): 
    dp = [[0 for i in range(N)] for j in range(N)] 
    dp[0][0] = table[0][0] 
    # Initialize first column of total table(dp) array 
    for i in range(0, N): 
        dp[i][0] = 0


    for j in range(0, N): 
        dp[0][j] = 0

    for i in range(0, N): 
        for j in range(0, N):
            print(i, j)
            if i == N-1 and j == N-1:
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
                continue
            if i == N-1 :
                dp[i][j] = table[i][j + 1]
                continue

            if j == N-1 :
                dp[i][j] = table[i + 1][j]
                continue
            dp[i][j] = max(table[i + 1][j], table[i][j + 1])

    return dp

但失敗了......

對於動態編程,您需要一個邊緣條件和一種在現在的位置得分的方法。 在此之后,它或多或少是聰明的蠻力。 智能部分來自記憶,所以你不要重復工作。

這是python的基本遞歸方法,它執行以下操作:

  • 組織奶酪表作為一組冷凍的元組。 這可以進行散列以進行記憶,並且您可以在恆定時間內確定位置在集合中。

  • 為結束創建邊緣條件(當兩個坐標都是N時)和當你離開地圖時的邊緣條件 - 只返回0。

  • 使用lru_cache進行memoize。 您可以輕松自己實現。


from functools import lru_cache

def hasCheese(table, location):
    ''' Helper function just to improve readability '''
    return 1 if location in table else 0

@lru_cache()
def maxC(table, N, location = (0, 0)):  

    # edge conditions final square and off the grid:  
    if location[0] == N and location[1] == N:
        return hasCheese(table, location)
    if any(l > N for l in location):
        return 0

    # recursion
    score_here = hasCheese(table, location)
    return max(score_here + maxC(table, N, (location[0] + 1, location[1])),
               score_here + maxC(table, N, (location[0], location[1] + 1))
              )

t = frozenset([(2, 3), (3, 2), (4, 3), (4, 5), (5, 2)])
N = 5

print(maxC(t, N))
# prints 3

如果要使用矩陣以自上而下的方式執行此操作,則需要非常小心,以便始終使用先前的索引集。 以這種方式犯錯是比較容易的,因為你需要獲得索引和順序正確。 當你將它設置為兩個嵌套的遞增循環時,這意味着下一個值總是當前單元格加上兩個單元格的最大值減去一個單位 - 你應該總是在矩陣中向后看。 當你期待這個時,目前還不清楚你想要做什么:

 dp[i][j] = table[i][j + 1]

因為還沒有確定j+1

由於奶酪坐標是1個索引,因此簡單的方法是使矩陣歸零,N + 1。 然后,當您在1處開始for循環時,您可以始終查看較低的索引而不會低估矩陣並避免大量的if/else邏輯。 例如:

def hasCheese(table, location):
    ''' Helper function just to improve readability '''
    return 1 if location in table else 0

def maxAverageOfPath(table, N): 
    # matrix is sized one unit bigger
    dp = [[0 for i in range(N+1)] for j in range(N+1)] 

    # iterate 1-5 inclusive
    for i in range(1, N+1): 
        for j in range(1, N+1):
            # because the zeroth row and column are already zero, this works without undershooting the table
            dp[i][j] = hasCheese(table, (i, j)) + max(dp[i][j-1], dp[i-1][j])
    # solution is in the corner
    return dp[N][N]

t = {(2, 3), (3, 2), (4, 3), (4, 5), (5, 2)}
N  = 5

print(maxAverageOfPath(t, N)) #3

當你完成后,你的矩陣看起來像:

[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 1, 1]
[0, 0, 1, 1, 1, 1]
[0, 0, 1, 2, 2, 3]
[0, 0, 2, 2, 2, 3]

您的起點是(1,1),從右上角開始,答案是左下角。

在每個點上,您有兩個進一步移動的選項:

  1. array [row] [col + 1]
  2. 數組[row + 1] [col]

因為我們必須找到一條涉及最大奶酪的道路。 它可以通過像下面的數組重復來解決相同的問題:

解決方案=>

array [i] [j] + Max(Recur(array [i] [j+1]), Recur(array [i+1] [j]));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM