ダイナミックプログラミングダイナミックプログラミング:金鉱


問題の定義
  • n x mの大きさの金鉱がある.金鉱は1 x 1の大きさの格子に分けられ、各格子には特定の大きさの金がある.
  • 採掘者は第1列から金の採掘を開始した.最初は、最初の列のいずれかの行から開始できます.次のm-1では、右上、右下、右下の3つの位置のいずれかに移動する必要があります.
  • 採掘者が得ることができる最大の金の大きさを出力するプログラムを作成してください.

  • 入力条件
  • のテストケースの最初の行では、nとmをスペースで区切ります.(1 <= n, m <= 20)
  • 行目では、n xmの黄金数をスペースで区切ります.(1<=位置あたりの黄金個数<=100)
  • しゅつりょくじょうけん
  • は、採掘者が得ることができる最大の金の大きさをテストする.
  • I/O例
    #입력1
    3 4
    1 3 3 2 2 1 4 1 0 6 4 7
    #출력1
    19
    
    #입력2
    4 4
    1 3 1 5 2 2 4 1 5 0 2 3 0 6 1 2
    #출력2
    16
    正しいコード
    n, m = map(int, input().split())
    array = list(map(int, input().split(" ")))
    
    n = 3
    m = 4
    array = [1,3,3,2
            ,2,1,4,1
            ,0,6,4,7]
    
    dp = []
    idx = 0
    
    for i in range(n):
      dp.append(array[idx:idx+m])
      idx += m
    
    for j in range(1, m): # 두번째 열부터 마지막열까지
        for i in range(n): # 첫번째 행부터 마지막 행까지
            # 왼쪽에서 오는 경우
            left = dp[i][j - 1]
    
            # 왼쪽 위에서 오는 경우
            if i == 0 : left_up = 0 # 위쪽 벽 넘으면 0
            else: left_up = dp[i-1][j-1]
    
            # 왼쪽 아래에서 오는 경우
            if i == n-1 : left_down = 0 # 아래쪽 벽 넘으면 0
            else: left_down = dp[i+1][j-1]
    
            dp[i][j] = dp[i][j] + max(left_up, left_down, left)
    
    result = 0
    for i in range(n):
        result = max(result, dp[i][m-1])
    print(result)
    ろんり
  • 金鉱のすべての位置について、以下の3つだけを考慮します.
    左上隅
  • から
  • まで
    左下角
  • から
  • まで
    左側の
  • からの
  • 受信者の観点で問題を説明し,上記3つの場合,dpテーブルの更新金が最も多かった.
  • 配列の値をdp[i][j]と表す.
  • 点火式は以下の通りである.
  • dp[i][j] = dp[i][j] + max(dp[i-1][j-1], dp[i+1][j-1], dp[i][j-1])
  • テーブルを離れるかどうかを確認する必要があります.
  • 配列変数
  • の記事の初期データを使用することなく、dpテーブルを使用できます.